2022-09-03 09:08:45 +00:00
|
|
|
import torch
|
2022-10-02 21:31:19 +00:00
|
|
|
from torch.nn.functional import silu
|
2023-01-12 14:03:46 +00:00
|
|
|
from types import MethodType
|
2022-09-03 09:08:45 +00:00
|
|
|
|
2023-09-11 18:17:28 +00:00
|
|
|
from modules import devices, sd_hijack_optimizations, shared, script_callbacks, errors, sd_unet, patches
|
2022-11-26 13:45:57 +00:00
|
|
|
from modules.hypernetworks import hypernetwork
|
2022-12-10 06:17:39 +00:00
|
|
|
from modules.shared import cmd_opts
|
2023-09-23 09:51:41 +00:00
|
|
|
from modules import sd_hijack_clip, sd_hijack_open_clip, sd_hijack_unet, sd_hijack_xlmr, xlmr, xlmr_m18
|
2022-11-26 13:10:46 +00:00
|
|
|
|
2022-09-04 22:41:20 +00:00
|
|
|
import ldm.modules.attention
|
2022-09-13 11:29:56 +00:00
|
|
|
import ldm.modules.diffusionmodules.model
|
2022-12-02 12:47:02 +00:00
|
|
|
import ldm.modules.diffusionmodules.openaimodel
|
2023-09-11 18:17:28 +00:00
|
|
|
import ldm.models.diffusion.ddpm
|
2022-11-11 15:20:18 +00:00
|
|
|
import ldm.models.diffusion.ddim
|
|
|
|
import ldm.models.diffusion.plms
|
2022-11-26 13:10:46 +00:00
|
|
|
import ldm.modules.encoders.modules
|
2022-09-13 11:29:56 +00:00
|
|
|
|
2023-07-12 20:52:43 +00:00
|
|
|
import sgm.modules.attention
|
|
|
|
import sgm.modules.diffusionmodules.model
|
|
|
|
import sgm.modules.diffusionmodules.openaimodel
|
|
|
|
import sgm.modules.encoders.modules
|
|
|
|
|
2022-10-02 12:03:39 +00:00
|
|
|
attention_CrossAttention_forward = ldm.modules.attention.CrossAttention.forward
|
|
|
|
diffusionmodules_model_nonlinearity = ldm.modules.diffusionmodules.model.nonlinearity
|
|
|
|
diffusionmodules_model_AttnBlock_forward = ldm.modules.diffusionmodules.model.AttnBlock.forward
|
2022-09-13 11:29:56 +00:00
|
|
|
|
2022-11-26 13:10:46 +00:00
|
|
|
# new memory efficient cross attention blocks do not support hypernets and we already
|
|
|
|
# have memory efficient cross attention anyway, so this disables SD2.0's memory efficient cross attention
|
|
|
|
ldm.modules.attention.MemoryEfficientCrossAttention = ldm.modules.attention.CrossAttention
|
|
|
|
ldm.modules.attention.BasicTransformerBlock.ATTENTION_MODES["softmax-xformers"] = ldm.modules.attention.CrossAttention
|
|
|
|
|
|
|
|
# silence new console spam from SD2
|
2023-07-31 21:24:48 +00:00
|
|
|
ldm.modules.attention.print = shared.ldm_print
|
|
|
|
ldm.modules.diffusionmodules.model.print = shared.ldm_print
|
|
|
|
ldm.util.print = shared.ldm_print
|
|
|
|
ldm.models.diffusion.ddpm.print = shared.ldm_print
|
2022-10-15 13:59:37 +00:00
|
|
|
|
2023-05-18 19:48:28 +00:00
|
|
|
optimizers = []
|
|
|
|
current_optimizer: sd_hijack_optimizations.SdOptimization = None
|
|
|
|
|
|
|
|
def list_optimizers():
|
|
|
|
new_optimizers = script_callbacks.list_optimizers_callback()
|
|
|
|
|
|
|
|
new_optimizers = [x for x in new_optimizers if x.is_available()]
|
|
|
|
|
2023-05-19 07:05:07 +00:00
|
|
|
new_optimizers = sorted(new_optimizers, key=lambda x: x.priority, reverse=True)
|
2023-05-18 19:48:28 +00:00
|
|
|
|
|
|
|
optimizers.clear()
|
|
|
|
optimizers.extend(new_optimizers)
|
|
|
|
|
2022-12-10 06:14:30 +00:00
|
|
|
|
2023-05-27 12:47:33 +00:00
|
|
|
def apply_optimizations(option=None):
|
2023-05-18 19:48:28 +00:00
|
|
|
global current_optimizer
|
|
|
|
|
2022-10-07 13:39:51 +00:00
|
|
|
undo_optimizations()
|
|
|
|
|
2023-05-23 15:02:09 +00:00
|
|
|
if len(optimizers) == 0:
|
|
|
|
# a script can access the model very early, and optimizations would not be filled by then
|
|
|
|
current_optimizer = None
|
|
|
|
return ''
|
|
|
|
|
2022-10-02 21:31:19 +00:00
|
|
|
ldm.modules.diffusionmodules.model.nonlinearity = silu
|
2022-12-10 06:14:30 +00:00
|
|
|
ldm.modules.diffusionmodules.openaimodel.th = sd_hijack_unet.th
|
2023-05-11 15:28:15 +00:00
|
|
|
|
2023-07-12 20:52:43 +00:00
|
|
|
sgm.modules.diffusionmodules.model.nonlinearity = silu
|
|
|
|
sgm.modules.diffusionmodules.openaimodel.th = sd_hijack_unet.th
|
|
|
|
|
2023-05-18 19:48:28 +00:00
|
|
|
if current_optimizer is not None:
|
|
|
|
current_optimizer.undo()
|
|
|
|
current_optimizer = None
|
|
|
|
|
2023-05-27 12:47:33 +00:00
|
|
|
selection = option or shared.opts.cross_attention_optimization
|
2023-05-18 19:48:28 +00:00
|
|
|
if selection == "Automatic" and len(optimizers) > 0:
|
|
|
|
matching_optimizer = next(iter([x for x in optimizers if x.cmd_opt and getattr(shared.cmd_opts, x.cmd_opt, False)]), optimizers[0])
|
|
|
|
else:
|
|
|
|
matching_optimizer = next(iter([x for x in optimizers if x.title() == selection]), None)
|
2022-09-13 11:29:56 +00:00
|
|
|
|
2023-05-18 19:48:28 +00:00
|
|
|
if selection == "None":
|
|
|
|
matching_optimizer = None
|
2023-06-01 05:12:06 +00:00
|
|
|
elif selection == "Automatic" and shared.cmd_opts.disable_opt_split_attention:
|
|
|
|
matching_optimizer = None
|
2023-05-18 19:48:28 +00:00
|
|
|
elif matching_optimizer is None:
|
|
|
|
matching_optimizer = optimizers[0]
|
|
|
|
|
|
|
|
if matching_optimizer is not None:
|
2023-05-27 12:47:33 +00:00
|
|
|
print(f"Applying attention optimization: {matching_optimizer.name}... ", end='')
|
2023-05-18 19:48:28 +00:00
|
|
|
matching_optimizer.apply()
|
2023-05-23 15:02:09 +00:00
|
|
|
print("done.")
|
2023-05-18 19:48:28 +00:00
|
|
|
current_optimizer = matching_optimizer
|
|
|
|
return current_optimizer.name
|
|
|
|
else:
|
2023-05-27 12:47:33 +00:00
|
|
|
print("Disabling attention optimization")
|
2023-05-18 19:48:28 +00:00
|
|
|
return ''
|
2022-09-13 11:29:56 +00:00
|
|
|
|
|
|
|
|
2022-10-02 12:03:39 +00:00
|
|
|
def undo_optimizations():
|
|
|
|
ldm.modules.diffusionmodules.model.nonlinearity = diffusionmodules_model_nonlinearity
|
2023-05-18 19:48:28 +00:00
|
|
|
ldm.modules.attention.CrossAttention.forward = hypernetwork.attention_CrossAttention_forward
|
2022-10-02 12:03:39 +00:00
|
|
|
ldm.modules.diffusionmodules.model.AttnBlock.forward = diffusionmodules_model_AttnBlock_forward
|
2022-09-13 11:29:56 +00:00
|
|
|
|
2023-07-12 20:52:43 +00:00
|
|
|
sgm.modules.diffusionmodules.model.nonlinearity = diffusionmodules_model_nonlinearity
|
|
|
|
sgm.modules.attention.CrossAttention.forward = hypernetwork.attention_CrossAttention_forward
|
|
|
|
sgm.modules.diffusionmodules.model.AttnBlock.forward = diffusionmodules_model_AttnBlock_forward
|
|
|
|
|
2022-09-03 09:08:45 +00:00
|
|
|
|
2023-01-19 17:39:03 +00:00
|
|
|
def fix_checkpoint():
|
|
|
|
"""checkpoints are now added and removed in embedding/hypernet code, since torch doesn't want
|
|
|
|
checkpoints to be added when not training (there's a warning)"""
|
|
|
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
2023-01-12 14:03:46 +00:00
|
|
|
def weighted_loss(sd_model, pred, target, mean=True):
|
|
|
|
#Calculate the weight normally, but ignore the mean
|
|
|
|
loss = sd_model._old_get_loss(pred, target, mean=False)
|
2023-05-11 15:28:15 +00:00
|
|
|
|
2023-01-12 14:03:46 +00:00
|
|
|
#Check if we have weights available
|
|
|
|
weight = getattr(sd_model, '_custom_loss_weight', None)
|
|
|
|
if weight is not None:
|
|
|
|
loss *= weight
|
2023-05-11 15:28:15 +00:00
|
|
|
|
2023-01-12 14:03:46 +00:00
|
|
|
#Return the loss, as mean if specified
|
|
|
|
return loss.mean() if mean else loss
|
|
|
|
|
|
|
|
def weighted_forward(sd_model, x, c, w, *args, **kwargs):
|
|
|
|
try:
|
|
|
|
#Temporarily append weights to a place accessible during loss calc
|
|
|
|
sd_model._custom_loss_weight = w
|
2023-05-11 15:28:15 +00:00
|
|
|
|
2023-01-12 14:03:46 +00:00
|
|
|
#Replace 'get_loss' with a weight-aware one. Otherwise we need to reimplement 'forward' completely
|
|
|
|
#Keep 'get_loss', but don't overwrite the previous old_get_loss if it's already set
|
|
|
|
if not hasattr(sd_model, '_old_get_loss'):
|
|
|
|
sd_model._old_get_loss = sd_model.get_loss
|
|
|
|
sd_model.get_loss = MethodType(weighted_loss, sd_model)
|
|
|
|
|
|
|
|
#Run the standard forward function, but with the patched 'get_loss'
|
|
|
|
return sd_model.forward(x, c, *args, **kwargs)
|
|
|
|
finally:
|
|
|
|
try:
|
|
|
|
#Delete temporary weights if appended
|
|
|
|
del sd_model._custom_loss_weight
|
2023-05-10 04:52:45 +00:00
|
|
|
except AttributeError:
|
2023-01-12 14:03:46 +00:00
|
|
|
pass
|
2023-05-11 15:28:15 +00:00
|
|
|
|
2023-01-12 14:03:46 +00:00
|
|
|
#If we have an old loss function, reset the loss function to the original one
|
|
|
|
if hasattr(sd_model, '_old_get_loss'):
|
|
|
|
sd_model.get_loss = sd_model._old_get_loss
|
|
|
|
del sd_model._old_get_loss
|
|
|
|
|
|
|
|
def apply_weighted_forward(sd_model):
|
|
|
|
#Add new function 'weighted_forward' that can be called to calc weighted loss
|
|
|
|
sd_model.weighted_forward = MethodType(weighted_forward, sd_model)
|
|
|
|
|
|
|
|
def undo_weighted_forward(sd_model):
|
|
|
|
try:
|
|
|
|
del sd_model.weighted_forward
|
2023-05-10 04:52:45 +00:00
|
|
|
except AttributeError:
|
2023-01-12 14:03:46 +00:00
|
|
|
pass
|
|
|
|
|
|
|
|
|
2022-09-03 09:08:45 +00:00
|
|
|
class StableDiffusionModelHijack:
|
|
|
|
fixes = None
|
2022-09-05 00:25:37 +00:00
|
|
|
layers = None
|
|
|
|
circular_enabled = False
|
2022-09-27 19:56:18 +00:00
|
|
|
clip = None
|
2023-01-04 13:04:38 +00:00
|
|
|
optimization_method = None
|
2022-09-03 09:08:45 +00:00
|
|
|
|
2023-01-08 06:37:33 +00:00
|
|
|
def __init__(self):
|
2023-08-04 06:09:09 +00:00
|
|
|
import modules.textual_inversion.textual_inversion
|
|
|
|
|
2023-07-15 05:41:22 +00:00
|
|
|
self.extra_generation_params = {}
|
|
|
|
self.comments = []
|
|
|
|
|
2023-08-04 06:09:09 +00:00
|
|
|
self.embedding_db = modules.textual_inversion.textual_inversion.EmbeddingDatabase()
|
2023-01-08 06:37:33 +00:00
|
|
|
self.embedding_db.add_embedding_dir(cmd_opts.embeddings_dir)
|
2022-11-30 02:13:17 +00:00
|
|
|
|
2023-05-27 12:47:33 +00:00
|
|
|
def apply_optimizations(self, option=None):
|
2023-05-23 15:02:09 +00:00
|
|
|
try:
|
2023-05-27 12:47:33 +00:00
|
|
|
self.optimization_method = apply_optimizations(option)
|
2023-05-23 15:02:09 +00:00
|
|
|
except Exception as e:
|
|
|
|
errors.display(e, "applying cross attention optimization")
|
|
|
|
undo_optimizations()
|
2023-11-05 16:32:21 +00:00
|
|
|
|
2023-11-05 16:46:20 +00:00
|
|
|
def convert_sdxl_to_ssd(self, m):
|
|
|
|
"""Converts an SDXL model to a Segmind Stable Diffusion model (see https://huggingface.co/segmind/SSD-1B)"""
|
|
|
|
|
|
|
|
delattr(m.model.diffusion_model.middle_block, '1')
|
|
|
|
delattr(m.model.diffusion_model.middle_block, '2')
|
|
|
|
for i in ['9', '8', '7', '6', '5', '4']:
|
|
|
|
delattr(m.model.diffusion_model.input_blocks[7][1].transformer_blocks, i)
|
|
|
|
delattr(m.model.diffusion_model.input_blocks[8][1].transformer_blocks, i)
|
|
|
|
delattr(m.model.diffusion_model.output_blocks[0][1].transformer_blocks, i)
|
|
|
|
delattr(m.model.diffusion_model.output_blocks[1][1].transformer_blocks, i)
|
|
|
|
delattr(m.model.diffusion_model.output_blocks[4][1].transformer_blocks, '1')
|
|
|
|
delattr(m.model.diffusion_model.output_blocks[5][1].transformer_blocks, '1')
|
|
|
|
devices.torch_gc()
|
2023-05-23 15:02:09 +00:00
|
|
|
|
2023-01-08 06:37:33 +00:00
|
|
|
def hijack(self, m):
|
2023-07-11 18:16:43 +00:00
|
|
|
conditioner = getattr(m, 'conditioner', None)
|
|
|
|
if conditioner:
|
2023-07-14 06:16:01 +00:00
|
|
|
text_cond_models = []
|
|
|
|
|
2023-07-11 18:16:43 +00:00
|
|
|
for i in range(len(conditioner.embedders)):
|
|
|
|
embedder = conditioner.embedders[i]
|
2023-07-12 20:52:43 +00:00
|
|
|
typename = type(embedder).__name__
|
|
|
|
if typename == 'FrozenOpenCLIPEmbedder':
|
2023-07-11 18:16:43 +00:00
|
|
|
embedder.model.token_embedding = EmbeddingsWithFixes(embedder.model.token_embedding, self)
|
2023-07-14 06:16:01 +00:00
|
|
|
conditioner.embedders[i] = sd_hijack_open_clip.FrozenOpenCLIPEmbedderWithCustomWords(embedder, self)
|
|
|
|
text_cond_models.append(conditioner.embedders[i])
|
2023-07-12 20:52:43 +00:00
|
|
|
if typename == 'FrozenCLIPEmbedder':
|
2023-07-14 06:16:01 +00:00
|
|
|
model_embeddings = embedder.transformer.text_model.embeddings
|
2023-07-12 20:52:43 +00:00
|
|
|
model_embeddings.token_embedding = EmbeddingsWithFixes(model_embeddings.token_embedding, self)
|
2023-07-14 06:16:01 +00:00
|
|
|
conditioner.embedders[i] = sd_hijack_clip.FrozenCLIPEmbedderForSDXLWithCustomWords(embedder, self)
|
|
|
|
text_cond_models.append(conditioner.embedders[i])
|
2023-07-12 20:52:43 +00:00
|
|
|
if typename == 'FrozenOpenCLIPEmbedder2':
|
2023-07-29 12:15:06 +00:00
|
|
|
embedder.model.token_embedding = EmbeddingsWithFixes(embedder.model.token_embedding, self, textual_inversion_key='clip_g')
|
2023-07-12 20:52:43 +00:00
|
|
|
conditioner.embedders[i] = sd_hijack_open_clip.FrozenOpenCLIPEmbedder2WithCustomWords(embedder, self)
|
2023-07-14 06:16:01 +00:00
|
|
|
text_cond_models.append(conditioner.embedders[i])
|
|
|
|
|
|
|
|
if len(text_cond_models) == 1:
|
|
|
|
m.cond_stage_model = text_cond_models[0]
|
|
|
|
else:
|
|
|
|
m.cond_stage_model = conditioner
|
2023-07-11 18:16:43 +00:00
|
|
|
|
2023-09-23 09:51:41 +00:00
|
|
|
if type(m.cond_stage_model) == xlmr.BertSeriesModelWithTransformation or type(m.cond_stage_model) == xlmr_m18.BertSeriesModelWithTransformation:
|
2022-11-30 06:56:12 +00:00
|
|
|
model_embeddings = m.cond_stage_model.roberta.embeddings
|
|
|
|
model_embeddings.token_embedding = EmbeddingsWithFixes(model_embeddings.word_embeddings, self)
|
2022-12-31 15:06:35 +00:00
|
|
|
m.cond_stage_model = sd_hijack_xlmr.FrozenXLMREmbedderWithCustomWords(m.cond_stage_model, self)
|
|
|
|
|
2022-11-30 06:56:12 +00:00
|
|
|
elif type(m.cond_stage_model) == ldm.modules.encoders.modules.FrozenCLIPEmbedder:
|
2022-11-26 13:10:46 +00:00
|
|
|
model_embeddings = m.cond_stage_model.transformer.text_model.embeddings
|
|
|
|
model_embeddings.token_embedding = EmbeddingsWithFixes(model_embeddings.token_embedding, self)
|
|
|
|
m.cond_stage_model = sd_hijack_clip.FrozenCLIPEmbedderWithCustomWords(m.cond_stage_model, self)
|
2022-12-31 15:06:35 +00:00
|
|
|
|
2022-11-26 13:10:46 +00:00
|
|
|
elif type(m.cond_stage_model) == ldm.modules.encoders.modules.FrozenOpenCLIPEmbedder:
|
|
|
|
m.cond_stage_model.model.token_embedding = EmbeddingsWithFixes(m.cond_stage_model.model.token_embedding, self)
|
|
|
|
m.cond_stage_model = sd_hijack_open_clip.FrozenOpenCLIPEmbedderWithCustomWords(m.cond_stage_model, self)
|
2022-12-31 15:06:35 +00:00
|
|
|
|
2023-01-12 14:03:46 +00:00
|
|
|
apply_weighted_forward(m)
|
2023-02-07 05:05:54 +00:00
|
|
|
if m.cond_stage_key == "edit":
|
|
|
|
sd_hijack_unet.hijack_ddpm_edit()
|
2023-01-12 14:03:46 +00:00
|
|
|
|
2023-05-23 15:02:09 +00:00
|
|
|
self.apply_optimizations()
|
2022-12-31 15:06:35 +00:00
|
|
|
|
2022-09-27 19:56:18 +00:00
|
|
|
self.clip = m.cond_stage_model
|
2022-09-04 22:41:20 +00:00
|
|
|
|
2022-09-05 00:25:37 +00:00
|
|
|
def flatten(el):
|
|
|
|
flattened = [flatten(children) for children in el.children()]
|
|
|
|
res = [el]
|
|
|
|
for c in flattened:
|
|
|
|
res += c
|
|
|
|
return res
|
|
|
|
|
|
|
|
self.layers = flatten(m)
|
|
|
|
|
2023-11-06 08:17:36 +00:00
|
|
|
import modules.models.diffusion.ddpm_edit
|
|
|
|
|
2023-12-02 03:56:08 +00:00
|
|
|
ldm_original_forward = patches.patch(__file__, ldm.modules.diffusionmodules.openaimodel.UNetModel, "forward", sd_unet.UNetModel_forward)
|
|
|
|
sgm_original_forward = patches.patch(__file__, sgm.modules.diffusionmodules.openaimodel.UNetModel, "forward", sd_unet.UNetModel_forward)
|
|
|
|
|
2023-09-11 18:17:28 +00:00
|
|
|
if isinstance(m, ldm.models.diffusion.ddpm.LatentDiffusion):
|
|
|
|
sd_unet.original_forward = ldm_original_forward
|
2023-11-06 08:17:36 +00:00
|
|
|
elif isinstance(m, modules.models.diffusion.ddpm_edit.LatentDiffusion):
|
|
|
|
sd_unet.original_forward = ldm_original_forward
|
2023-09-11 18:17:28 +00:00
|
|
|
elif isinstance(m, sgm.models.diffusion.DiffusionEngine):
|
|
|
|
sd_unet.original_forward = sgm_original_forward
|
|
|
|
else:
|
|
|
|
sd_unet.original_forward = None
|
2023-05-27 12:47:33 +00:00
|
|
|
|
|
|
|
|
2022-09-29 12:40:28 +00:00
|
|
|
def undo_hijack(self, m):
|
2023-08-19 07:16:27 +00:00
|
|
|
conditioner = getattr(m, 'conditioner', None)
|
|
|
|
if conditioner:
|
|
|
|
for i in range(len(conditioner.embedders)):
|
|
|
|
embedder = conditioner.embedders[i]
|
|
|
|
if isinstance(embedder, (sd_hijack_open_clip.FrozenOpenCLIPEmbedderWithCustomWords, sd_hijack_open_clip.FrozenOpenCLIPEmbedder2WithCustomWords)):
|
|
|
|
embedder.wrapped.model.token_embedding = embedder.wrapped.model.token_embedding.wrapped
|
|
|
|
conditioner.embedders[i] = embedder.wrapped
|
|
|
|
if isinstance(embedder, sd_hijack_clip.FrozenCLIPEmbedderForSDXLWithCustomWords):
|
|
|
|
embedder.wrapped.transformer.text_model.embeddings.token_embedding = embedder.wrapped.transformer.text_model.embeddings.token_embedding.wrapped
|
|
|
|
conditioner.embedders[i] = embedder.wrapped
|
|
|
|
|
|
|
|
if hasattr(m, 'cond_stage_model'):
|
|
|
|
delattr(m, 'cond_stage_model')
|
|
|
|
|
|
|
|
elif type(m.cond_stage_model) == sd_hijack_xlmr.FrozenXLMREmbedderWithCustomWords:
|
2023-05-11 15:28:15 +00:00
|
|
|
m.cond_stage_model = m.cond_stage_model.wrapped
|
2022-12-06 08:04:50 +00:00
|
|
|
|
|
|
|
elif type(m.cond_stage_model) == sd_hijack_clip.FrozenCLIPEmbedderWithCustomWords:
|
2022-09-29 12:40:28 +00:00
|
|
|
m.cond_stage_model = m.cond_stage_model.wrapped
|
|
|
|
|
2022-11-26 13:10:46 +00:00
|
|
|
model_embeddings = m.cond_stage_model.transformer.text_model.embeddings
|
|
|
|
if type(model_embeddings.token_embedding) == EmbeddingsWithFixes:
|
|
|
|
model_embeddings.token_embedding = model_embeddings.token_embedding.wrapped
|
|
|
|
elif type(m.cond_stage_model) == sd_hijack_open_clip.FrozenOpenCLIPEmbedderWithCustomWords:
|
|
|
|
m.cond_stage_model.wrapped.model.token_embedding = m.cond_stage_model.wrapped.model.token_embedding.wrapped
|
|
|
|
m.cond_stage_model = m.cond_stage_model.wrapped
|
2022-09-29 12:40:28 +00:00
|
|
|
|
2023-01-28 12:24:29 +00:00
|
|
|
undo_optimizations()
|
2023-01-12 14:03:46 +00:00
|
|
|
undo_weighted_forward(m)
|
2023-01-28 12:24:29 +00:00
|
|
|
|
2022-11-18 10:22:55 +00:00
|
|
|
self.apply_circular(False)
|
2022-11-01 07:01:49 +00:00
|
|
|
self.layers = None
|
|
|
|
self.clip = None
|
|
|
|
|
2023-12-02 03:56:08 +00:00
|
|
|
patches.undo(__file__, ldm.modules.diffusionmodules.openaimodel.UNetModel, "forward")
|
|
|
|
patches.undo(__file__, sgm.modules.diffusionmodules.openaimodel.UNetModel, "forward")
|
|
|
|
|
2023-09-11 18:17:28 +00:00
|
|
|
sd_unet.original_forward = None
|
|
|
|
|
2023-05-27 12:47:33 +00:00
|
|
|
|
2022-09-05 00:25:37 +00:00
|
|
|
def apply_circular(self, enable):
|
|
|
|
if self.circular_enabled == enable:
|
|
|
|
return
|
|
|
|
|
|
|
|
self.circular_enabled = enable
|
|
|
|
|
|
|
|
for layer in [layer for layer in self.layers if type(layer) == torch.nn.Conv2d]:
|
|
|
|
layer.padding_mode = 'circular' if enable else 'zeros'
|
|
|
|
|
2022-10-07 21:48:34 +00:00
|
|
|
def clear_comments(self):
|
|
|
|
self.comments = []
|
2023-07-15 05:41:22 +00:00
|
|
|
self.extra_generation_params = {}
|
2022-10-07 21:48:34 +00:00
|
|
|
|
2023-01-06 22:45:28 +00:00
|
|
|
def get_prompt_lengths(self, text):
|
2023-05-14 10:27:50 +00:00
|
|
|
if self.clip is None:
|
|
|
|
return "-", "-"
|
|
|
|
|
2023-01-06 22:45:28 +00:00
|
|
|
_, token_count = self.clip.process_texts([text])
|
2022-09-03 09:08:45 +00:00
|
|
|
|
2023-01-06 22:45:28 +00:00
|
|
|
return token_count, self.clip.get_target_prompt_token_count(token_count)
|
2022-09-03 09:08:45 +00:00
|
|
|
|
2023-05-18 19:48:28 +00:00
|
|
|
def redo_hijack(self, m):
|
|
|
|
self.undo_hijack(m)
|
|
|
|
self.hijack(m)
|
|
|
|
|
2022-09-03 09:08:45 +00:00
|
|
|
|
|
|
|
class EmbeddingsWithFixes(torch.nn.Module):
|
2023-07-29 12:15:06 +00:00
|
|
|
def __init__(self, wrapped, embeddings, textual_inversion_key='clip_l'):
|
2022-09-03 09:08:45 +00:00
|
|
|
super().__init__()
|
|
|
|
self.wrapped = wrapped
|
|
|
|
self.embeddings = embeddings
|
2023-07-29 12:15:06 +00:00
|
|
|
self.textual_inversion_key = textual_inversion_key
|
2022-09-03 09:08:45 +00:00
|
|
|
|
|
|
|
def forward(self, input_ids):
|
|
|
|
batch_fixes = self.embeddings.fixes
|
|
|
|
self.embeddings.fixes = None
|
|
|
|
|
|
|
|
inputs_embeds = self.wrapped(input_ids)
|
|
|
|
|
2022-10-02 12:03:39 +00:00
|
|
|
if batch_fixes is None or len(batch_fixes) == 0 or max([len(x) for x in batch_fixes]) == 0:
|
|
|
|
return inputs_embeds
|
|
|
|
|
|
|
|
vecs = []
|
|
|
|
for fixes, tensor in zip(batch_fixes, inputs_embeds):
|
|
|
|
for offset, embedding in fixes:
|
2023-07-29 12:15:06 +00:00
|
|
|
vec = embedding.vec[self.textual_inversion_key] if isinstance(embedding.vec, dict) else embedding.vec
|
|
|
|
emb = devices.cond_cast_unet(vec)
|
2022-10-15 13:59:37 +00:00
|
|
|
emb_len = min(tensor.shape[0] - offset - 1, emb.shape[0])
|
|
|
|
tensor = torch.cat([tensor[0:offset + 1], emb[0:emb_len], tensor[offset + 1 + emb_len:]])
|
2022-10-02 12:03:39 +00:00
|
|
|
|
|
|
|
vecs.append(tensor)
|
2022-09-03 09:08:45 +00:00
|
|
|
|
2022-10-02 12:03:39 +00:00
|
|
|
return torch.stack(vecs)
|
2022-09-03 09:08:45 +00:00
|
|
|
|
|
|
|
|
2022-09-04 23:16:36 +00:00
|
|
|
def add_circular_option_to_conv_2d():
|
|
|
|
conv2d_constructor = torch.nn.Conv2d.__init__
|
2022-09-04 22:41:20 +00:00
|
|
|
|
2022-09-04 23:16:36 +00:00
|
|
|
def conv2d_constructor_circular(self, *args, **kwargs):
|
|
|
|
return conv2d_constructor(self, *args, padding_mode='circular', **kwargs)
|
2022-09-04 22:41:20 +00:00
|
|
|
|
2022-09-04 23:16:36 +00:00
|
|
|
torch.nn.Conv2d.__init__ = conv2d_constructor_circular
|
2022-09-04 22:41:20 +00:00
|
|
|
|
|
|
|
|
2022-09-03 09:08:45 +00:00
|
|
|
model_hijack = StableDiffusionModelHijack()
|
2022-11-11 15:20:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
def register_buffer(self, name, attr):
|
|
|
|
"""
|
|
|
|
Fix register buffer bug for Mac OS.
|
|
|
|
"""
|
|
|
|
|
|
|
|
if type(attr) == torch.Tensor:
|
|
|
|
if attr.device != devices.device:
|
2022-11-12 07:17:55 +00:00
|
|
|
attr = attr.to(device=devices.device, dtype=(torch.float32 if devices.device.type == 'mps' else None))
|
2022-11-11 15:20:18 +00:00
|
|
|
|
|
|
|
setattr(self, name, attr)
|
|
|
|
|
|
|
|
|
|
|
|
ldm.models.diffusion.ddim.DDIMSampler.register_buffer = register_buffer
|
|
|
|
ldm.models.diffusion.plms.PLMSSampler.register_buffer = register_buffer
|