remove everything related to training

This commit is contained in:
layerdiffusion
2024-08-05 04:29:23 -07:00
parent bd5a840519
commit 77a4980f08
31 changed files with 347 additions and 2202 deletions

View File

@@ -5,14 +5,12 @@ import os
import inspect
from contextlib import closing
import modules.textual_inversion.dataset
import torch
import tqdm
from einops import rearrange, repeat
from backend.nn.unet import default
from modules import devices, sd_models, shared, sd_samplers, hashes, sd_hijack_checkpoint, errors
from modules.textual_inversion import textual_inversion, saving_settings
from modules.textual_inversion.learn_schedule import LearnRateScheduler
from modules.textual_inversion import textual_inversion
from torch import einsum
from torch.nn.init import normal_, xavier_normal_, xavier_uniform_, kaiming_normal_, kaiming_uniform_, zeros_
@@ -436,348 +434,348 @@ def statistics(data):
recent_information = f"recent 32 loss:{mean(recent_data):.3f}" + u"\u00B1" + f"({std / (len(recent_data) ** 0.5):.3f})"
return total_information, recent_information
def create_hypernetwork(name, enable_sizes, overwrite_old, layer_structure=None, activation_func=None, weight_init=None, add_layer_norm=False, use_dropout=False, dropout_structure=None):
# Remove illegal characters from name.
name = "".join( x for x in name if (x.isalnum() or x in "._- "))
assert name, "Name cannot be empty!"
fn = os.path.join(shared.cmd_opts.hypernetwork_dir, f"{name}.pt")
if not overwrite_old:
assert not os.path.exists(fn), f"file {fn} already exists"
if type(layer_structure) == str:
layer_structure = [float(x.strip()) for x in layer_structure.split(",")]
if use_dropout and dropout_structure and type(dropout_structure) == str:
dropout_structure = [float(x.strip()) for x in dropout_structure.split(",")]
else:
dropout_structure = [0] * len(layer_structure)
hypernet = modules.hypernetworks.hypernetwork.Hypernetwork(
name=name,
enable_sizes=[int(x) for x in enable_sizes],
layer_structure=layer_structure,
activation_func=activation_func,
weight_init=weight_init,
add_layer_norm=add_layer_norm,
use_dropout=use_dropout,
dropout_structure=dropout_structure
)
hypernet.save(fn)
shared.reload_hypernetworks()
def train_hypernetwork(id_task, hypernetwork_name: str, learn_rate: float, batch_size: int, gradient_step: int, data_root: str, log_directory: str, training_width: int, training_height: int, varsize: bool, steps: int, clip_grad_mode: str, clip_grad_value: float, shuffle_tags: bool, tag_drop_out: bool, latent_sampling_method: str, use_weight: bool, create_image_every: int, save_hypernetwork_every: int, template_filename: str, preview_from_txt2img: bool, preview_prompt: str, preview_negative_prompt: str, preview_steps: int, preview_sampler_name: str, preview_cfg_scale: float, preview_seed: int, preview_width: int, preview_height: int):
from modules import images, processing
save_hypernetwork_every = save_hypernetwork_every or 0
create_image_every = create_image_every or 0
template_file = textual_inversion.textual_inversion_templates.get(template_filename, None)
textual_inversion.validate_train_inputs(hypernetwork_name, learn_rate, batch_size, gradient_step, data_root, template_file, template_filename, steps, save_hypernetwork_every, create_image_every, log_directory, name="hypernetwork")
template_file = template_file.path
path = shared.hypernetworks.get(hypernetwork_name, None)
hypernetwork = Hypernetwork()
hypernetwork.load(path)
shared.loaded_hypernetworks = [hypernetwork]
shared.state.job = "train-hypernetwork"
shared.state.textinfo = "Initializing hypernetwork training..."
shared.state.job_count = steps
hypernetwork_name = hypernetwork_name.rsplit('(', 1)[0]
filename = os.path.join(shared.cmd_opts.hypernetwork_dir, f'{hypernetwork_name}.pt')
log_directory = os.path.join(log_directory, datetime.datetime.now().strftime("%Y-%m-%d"), hypernetwork_name)
unload = shared.opts.unload_models_when_training
if save_hypernetwork_every > 0:
hypernetwork_dir = os.path.join(log_directory, "hypernetworks")
os.makedirs(hypernetwork_dir, exist_ok=True)
else:
hypernetwork_dir = None
if create_image_every > 0:
images_dir = os.path.join(log_directory, "images")
os.makedirs(images_dir, exist_ok=True)
else:
images_dir = None
checkpoint = sd_models.select_checkpoint()
initial_step = hypernetwork.step or 0
if initial_step >= steps:
shared.state.textinfo = "Model has already been trained beyond specified max steps"
return hypernetwork, filename
scheduler = LearnRateScheduler(learn_rate, steps, initial_step)
clip_grad = torch.nn.utils.clip_grad_value_ if clip_grad_mode == "value" else torch.nn.utils.clip_grad_norm_ if clip_grad_mode == "norm" else None
if clip_grad:
clip_grad_sched = LearnRateScheduler(clip_grad_value, steps, initial_step, verbose=False)
if shared.opts.training_enable_tensorboard:
tensorboard_writer = textual_inversion.tensorboard_setup(log_directory)
# dataset loading may take a while, so input validations and early returns should be done before this
shared.state.textinfo = f"Preparing dataset from {html.escape(data_root)}..."
pin_memory = shared.opts.pin_memory
ds = modules.textual_inversion.dataset.PersonalizedBase(data_root=data_root, width=training_width, height=training_height, repeats=shared.opts.training_image_repeats_per_epoch, placeholder_token=hypernetwork_name, model=shared.sd_model, cond_model=shared.sd_model.cond_stage_model, device=devices.device, template_file=template_file, include_cond=True, batch_size=batch_size, gradient_step=gradient_step, shuffle_tags=shuffle_tags, tag_drop_out=tag_drop_out, latent_sampling_method=latent_sampling_method, varsize=varsize, use_weight=use_weight)
if shared.opts.save_training_settings_to_txt:
saved_params = dict(
model_name=checkpoint.model_name, model_hash=checkpoint.shorthash, num_of_dataset_images=len(ds),
**{field: getattr(hypernetwork, field) for field in ['layer_structure', 'activation_func', 'weight_init', 'add_layer_norm', 'use_dropout', ]}
)
saving_settings.save_settings_to_file(log_directory, {**saved_params, **locals()})
latent_sampling_method = ds.latent_sampling_method
dl = modules.textual_inversion.dataset.PersonalizedDataLoader(ds, latent_sampling_method=latent_sampling_method, batch_size=ds.batch_size, pin_memory=pin_memory)
old_parallel_processing_allowed = shared.parallel_processing_allowed
if unload:
shared.parallel_processing_allowed = False
shared.sd_model.cond_stage_model.to(devices.cpu)
shared.sd_model.first_stage_model.to(devices.cpu)
weights = hypernetwork.weights()
hypernetwork.train()
# Here we use optimizer from saved HN, or we can specify as UI option.
if hypernetwork.optimizer_name in optimizer_dict:
optimizer = optimizer_dict[hypernetwork.optimizer_name](params=weights, lr=scheduler.learn_rate)
optimizer_name = hypernetwork.optimizer_name
else:
print(f"Optimizer type {hypernetwork.optimizer_name} is not defined!")
optimizer = torch.optim.AdamW(params=weights, lr=scheduler.learn_rate)
optimizer_name = 'AdamW'
if hypernetwork.optimizer_state_dict: # This line must be changed if Optimizer type can be different from saved optimizer.
try:
optimizer.load_state_dict(hypernetwork.optimizer_state_dict)
except RuntimeError as e:
print("Cannot resume from saved optimizer!")
print(e)
scaler = torch.cuda.amp.GradScaler()
batch_size = ds.batch_size
gradient_step = ds.gradient_step
# n steps = batch_size * gradient_step * n image processed
steps_per_epoch = len(ds) // batch_size // gradient_step
max_steps_per_epoch = len(ds) // batch_size - (len(ds) // batch_size) % gradient_step
loss_step = 0
_loss_step = 0 #internal
# size = len(ds.indexes)
# loss_dict = defaultdict(lambda : deque(maxlen = 1024))
loss_logging = deque(maxlen=len(ds) * 3) # this should be configurable parameter, this is 3 * epoch(dataset size)
# losses = torch.zeros((size,))
# previous_mean_losses = [0]
# previous_mean_loss = 0
# print("Mean loss of {} elements".format(size))
steps_without_grad = 0
last_saved_file = "<none>"
last_saved_image = "<none>"
forced_filename = "<none>"
pbar = tqdm.tqdm(total=steps - initial_step)
try:
sd_hijack_checkpoint.add()
for _ in range((steps-initial_step) * gradient_step):
if scheduler.finished:
break
if shared.state.interrupted:
break
for j, batch in enumerate(dl):
# works as a drop_last=True for gradient accumulation
if j == max_steps_per_epoch:
break
scheduler.apply(optimizer, hypernetwork.step)
if scheduler.finished:
break
if shared.state.interrupted:
break
if clip_grad:
clip_grad_sched.step(hypernetwork.step)
with devices.autocast():
x = batch.latent_sample.to(devices.device, non_blocking=pin_memory)
if use_weight:
w = batch.weight.to(devices.device, non_blocking=pin_memory)
if tag_drop_out != 0 or shuffle_tags:
shared.sd_model.cond_stage_model.to(devices.device)
c = shared.sd_model.cond_stage_model(batch.cond_text).to(devices.device, non_blocking=pin_memory)
shared.sd_model.cond_stage_model.to(devices.cpu)
else:
c = stack_conds(batch.cond).to(devices.device, non_blocking=pin_memory)
if use_weight:
loss = shared.sd_model.weighted_forward(x, c, w)[0] / gradient_step
del w
else:
loss = shared.sd_model.forward(x, c)[0] / gradient_step
del x
del c
_loss_step += loss.item()
scaler.scale(loss).backward()
# go back until we reach gradient accumulation steps
if (j + 1) % gradient_step != 0:
continue
loss_logging.append(_loss_step)
if clip_grad:
clip_grad(weights, clip_grad_sched.learn_rate)
scaler.step(optimizer)
scaler.update()
hypernetwork.step += 1
pbar.update()
optimizer.zero_grad(set_to_none=True)
loss_step = _loss_step
_loss_step = 0
steps_done = hypernetwork.step + 1
epoch_num = hypernetwork.step // steps_per_epoch
epoch_step = hypernetwork.step % steps_per_epoch
description = f"Training hypernetwork [Epoch {epoch_num}: {epoch_step+1}/{steps_per_epoch}]loss: {loss_step:.7f}"
pbar.set_description(description)
if hypernetwork_dir is not None and steps_done % save_hypernetwork_every == 0:
# Before saving, change name to match current checkpoint.
hypernetwork_name_every = f'{hypernetwork_name}-{steps_done}'
last_saved_file = os.path.join(hypernetwork_dir, f'{hypernetwork_name_every}.pt')
hypernetwork.optimizer_name = optimizer_name
if shared.opts.save_optimizer_state:
hypernetwork.optimizer_state_dict = optimizer.state_dict()
save_hypernetwork(hypernetwork, checkpoint, hypernetwork_name, last_saved_file)
hypernetwork.optimizer_state_dict = None # dereference it after saving, to save memory.
if shared.opts.training_enable_tensorboard:
epoch_num = hypernetwork.step // len(ds)
epoch_step = hypernetwork.step - (epoch_num * len(ds)) + 1
mean_loss = sum(loss_logging) / len(loss_logging)
textual_inversion.tensorboard_add(tensorboard_writer, loss=mean_loss, global_step=hypernetwork.step, step=epoch_step, learn_rate=scheduler.learn_rate, epoch_num=epoch_num)
textual_inversion.write_loss(log_directory, "hypernetwork_loss.csv", hypernetwork.step, steps_per_epoch, {
"loss": f"{loss_step:.7f}",
"learn_rate": scheduler.learn_rate
})
if images_dir is not None and steps_done % create_image_every == 0:
forced_filename = f'{hypernetwork_name}-{steps_done}'
last_saved_image = os.path.join(images_dir, forced_filename)
hypernetwork.eval()
rng_state = torch.get_rng_state()
cuda_rng_state = None
if torch.cuda.is_available():
cuda_rng_state = torch.cuda.get_rng_state_all()
shared.sd_model.cond_stage_model.to(devices.device)
shared.sd_model.first_stage_model.to(devices.device)
p = processing.StableDiffusionProcessingTxt2Img(
sd_model=shared.sd_model,
do_not_save_grid=True,
do_not_save_samples=True,
)
p.disable_extra_networks = True
if preview_from_txt2img:
p.prompt = preview_prompt
p.negative_prompt = preview_negative_prompt
p.steps = preview_steps
p.sampler_name = sd_samplers.samplers_map[preview_sampler_name.lower()]
p.cfg_scale = preview_cfg_scale
p.seed = preview_seed
p.width = preview_width
p.height = preview_height
else:
p.prompt = batch.cond_text[0]
p.steps = 20
p.width = training_width
p.height = training_height
preview_text = p.prompt
with closing(p):
processed = processing.process_images(p)
image = processed.images[0] if len(processed.images) > 0 else None
if unload:
shared.sd_model.cond_stage_model.to(devices.cpu)
shared.sd_model.first_stage_model.to(devices.cpu)
torch.set_rng_state(rng_state)
if torch.cuda.is_available():
torch.cuda.set_rng_state_all(cuda_rng_state)
hypernetwork.train()
if image is not None:
shared.state.assign_current_image(image)
if shared.opts.training_enable_tensorboard and shared.opts.training_tensorboard_save_images:
textual_inversion.tensorboard_add_image(tensorboard_writer,
f"Validation at epoch {epoch_num}", image,
hypernetwork.step)
last_saved_image, last_text_info = images.save_image(image, images_dir, "", p.seed, p.prompt, shared.opts.samples_format, processed.infotexts[0], p=p, forced_filename=forced_filename, save_to_dirs=False)
last_saved_image += f", prompt: {preview_text}"
shared.state.job_no = hypernetwork.step
shared.state.textinfo = f"""
<p>
Loss: {loss_step:.7f}<br/>
Step: {steps_done}<br/>
Last prompt: {html.escape(batch.cond_text[0])}<br/>
Last saved hypernetwork: {html.escape(last_saved_file)}<br/>
Last saved image: {html.escape(last_saved_image)}<br/>
</p>
"""
except Exception:
errors.report("Exception in training hypernetwork", exc_info=True)
finally:
pbar.leave = False
pbar.close()
hypernetwork.eval()
sd_hijack_checkpoint.remove()
filename = os.path.join(shared.cmd_opts.hypernetwork_dir, f'{hypernetwork_name}.pt')
hypernetwork.optimizer_name = optimizer_name
if shared.opts.save_optimizer_state:
hypernetwork.optimizer_state_dict = optimizer.state_dict()
save_hypernetwork(hypernetwork, checkpoint, hypernetwork_name, filename)
del optimizer
hypernetwork.optimizer_state_dict = None # dereference it after saving, to save memory.
shared.sd_model.cond_stage_model.to(devices.device)
shared.sd_model.first_stage_model.to(devices.device)
shared.parallel_processing_allowed = old_parallel_processing_allowed
return hypernetwork, filename
def save_hypernetwork(hypernetwork, checkpoint, hypernetwork_name, filename):
old_hypernetwork_name = hypernetwork.name
old_sd_checkpoint = hypernetwork.sd_checkpoint if hasattr(hypernetwork, "sd_checkpoint") else None
old_sd_checkpoint_name = hypernetwork.sd_checkpoint_name if hasattr(hypernetwork, "sd_checkpoint_name") else None
try:
hypernetwork.sd_checkpoint = checkpoint.shorthash
hypernetwork.sd_checkpoint_name = checkpoint.model_name
hypernetwork.name = hypernetwork_name
hypernetwork.save(filename)
except:
hypernetwork.sd_checkpoint = old_sd_checkpoint
hypernetwork.sd_checkpoint_name = old_sd_checkpoint_name
hypernetwork.name = old_hypernetwork_name
raise
#
# def create_hypernetwork(name, enable_sizes, overwrite_old, layer_structure=None, activation_func=None, weight_init=None, add_layer_norm=False, use_dropout=False, dropout_structure=None):
# # Remove illegal characters from name.
# name = "".join( x for x in name if (x.isalnum() or x in "._- "))
# assert name, "Name cannot be empty!"
#
# fn = os.path.join(shared.cmd_opts.hypernetwork_dir, f"{name}.pt")
# if not overwrite_old:
# assert not os.path.exists(fn), f"file {fn} already exists"
#
# if type(layer_structure) == str:
# layer_structure = [float(x.strip()) for x in layer_structure.split(",")]
#
# if use_dropout and dropout_structure and type(dropout_structure) == str:
# dropout_structure = [float(x.strip()) for x in dropout_structure.split(",")]
# else:
# dropout_structure = [0] * len(layer_structure)
#
# hypernet = modules.hypernetworks.hypernetwork.Hypernetwork(
# name=name,
# enable_sizes=[int(x) for x in enable_sizes],
# layer_structure=layer_structure,
# activation_func=activation_func,
# weight_init=weight_init,
# add_layer_norm=add_layer_norm,
# use_dropout=use_dropout,
# dropout_structure=dropout_structure
# )
# hypernet.save(fn)
#
# shared.reload_hypernetworks()
#
#
# def train_hypernetwork(id_task, hypernetwork_name: str, learn_rate: float, batch_size: int, gradient_step: int, data_root: str, log_directory: str, training_width: int, training_height: int, varsize: bool, steps: int, clip_grad_mode: str, clip_grad_value: float, shuffle_tags: bool, tag_drop_out: bool, latent_sampling_method: str, use_weight: bool, create_image_every: int, save_hypernetwork_every: int, template_filename: str, preview_from_txt2img: bool, preview_prompt: str, preview_negative_prompt: str, preview_steps: int, preview_sampler_name: str, preview_cfg_scale: float, preview_seed: int, preview_width: int, preview_height: int):
# from modules import images, processing
#
# save_hypernetwork_every = save_hypernetwork_every or 0
# create_image_every = create_image_every or 0
# template_file = textual_inversion.textual_inversion_templates.get(template_filename, None)
# textual_inversion.validate_train_inputs(hypernetwork_name, learn_rate, batch_size, gradient_step, data_root, template_file, template_filename, steps, save_hypernetwork_every, create_image_every, log_directory, name="hypernetwork")
# template_file = template_file.path
#
# path = shared.hypernetworks.get(hypernetwork_name, None)
# hypernetwork = Hypernetwork()
# hypernetwork.load(path)
# shared.loaded_hypernetworks = [hypernetwork]
#
# shared.state.job = "train-hypernetwork"
# shared.state.textinfo = "Initializing hypernetwork training..."
# shared.state.job_count = steps
#
# hypernetwork_name = hypernetwork_name.rsplit('(', 1)[0]
# filename = os.path.join(shared.cmd_opts.hypernetwork_dir, f'{hypernetwork_name}.pt')
#
# log_directory = os.path.join(log_directory, datetime.datetime.now().strftime("%Y-%m-%d"), hypernetwork_name)
# unload = shared.opts.unload_models_when_training
#
# if save_hypernetwork_every > 0:
# hypernetwork_dir = os.path.join(log_directory, "hypernetworks")
# os.makedirs(hypernetwork_dir, exist_ok=True)
# else:
# hypernetwork_dir = None
#
# if create_image_every > 0:
# images_dir = os.path.join(log_directory, "images")
# os.makedirs(images_dir, exist_ok=True)
# else:
# images_dir = None
#
# checkpoint = sd_models.select_checkpoint()
#
# initial_step = hypernetwork.step or 0
# if initial_step >= steps:
# shared.state.textinfo = "Model has already been trained beyond specified max steps"
# return hypernetwork, filename
#
# scheduler = LearnRateScheduler(learn_rate, steps, initial_step)
#
# clip_grad = torch.nn.utils.clip_grad_value_ if clip_grad_mode == "value" else torch.nn.utils.clip_grad_norm_ if clip_grad_mode == "norm" else None
# if clip_grad:
# clip_grad_sched = LearnRateScheduler(clip_grad_value, steps, initial_step, verbose=False)
#
# if shared.opts.training_enable_tensorboard:
# tensorboard_writer = textual_inversion.tensorboard_setup(log_directory)
#
# # dataset loading may take a while, so input validations and early returns should be done before this
# shared.state.textinfo = f"Preparing dataset from {html.escape(data_root)}..."
#
# pin_memory = shared.opts.pin_memory
#
# ds = modules.textual_inversion.dataset.PersonalizedBase(data_root=data_root, width=training_width, height=training_height, repeats=shared.opts.training_image_repeats_per_epoch, placeholder_token=hypernetwork_name, model=shared.sd_model, cond_model=shared.sd_model.cond_stage_model, device=devices.device, template_file=template_file, include_cond=True, batch_size=batch_size, gradient_step=gradient_step, shuffle_tags=shuffle_tags, tag_drop_out=tag_drop_out, latent_sampling_method=latent_sampling_method, varsize=varsize, use_weight=use_weight)
#
# if shared.opts.save_training_settings_to_txt:
# saved_params = dict(
# model_name=checkpoint.model_name, model_hash=checkpoint.shorthash, num_of_dataset_images=len(ds),
# **{field: getattr(hypernetwork, field) for field in ['layer_structure', 'activation_func', 'weight_init', 'add_layer_norm', 'use_dropout', ]}
# )
# saving_settings.save_settings_to_file(log_directory, {**saved_params, **locals()})
#
# latent_sampling_method = ds.latent_sampling_method
#
# dl = modules.textual_inversion.dataset.PersonalizedDataLoader(ds, latent_sampling_method=latent_sampling_method, batch_size=ds.batch_size, pin_memory=pin_memory)
#
# old_parallel_processing_allowed = shared.parallel_processing_allowed
#
# if unload:
# shared.parallel_processing_allowed = False
# shared.sd_model.cond_stage_model.to(devices.cpu)
# shared.sd_model.first_stage_model.to(devices.cpu)
#
# weights = hypernetwork.weights()
# hypernetwork.train()
#
# # Here we use optimizer from saved HN, or we can specify as UI option.
# if hypernetwork.optimizer_name in optimizer_dict:
# optimizer = optimizer_dict[hypernetwork.optimizer_name](params=weights, lr=scheduler.learn_rate)
# optimizer_name = hypernetwork.optimizer_name
# else:
# print(f"Optimizer type {hypernetwork.optimizer_name} is not defined!")
# optimizer = torch.optim.AdamW(params=weights, lr=scheduler.learn_rate)
# optimizer_name = 'AdamW'
#
# if hypernetwork.optimizer_state_dict: # This line must be changed if Optimizer type can be different from saved optimizer.
# try:
# optimizer.load_state_dict(hypernetwork.optimizer_state_dict)
# except RuntimeError as e:
# print("Cannot resume from saved optimizer!")
# print(e)
#
# scaler = torch.cuda.amp.GradScaler()
#
# batch_size = ds.batch_size
# gradient_step = ds.gradient_step
# # n steps = batch_size * gradient_step * n image processed
# steps_per_epoch = len(ds) // batch_size // gradient_step
# max_steps_per_epoch = len(ds) // batch_size - (len(ds) // batch_size) % gradient_step
# loss_step = 0
# _loss_step = 0 #internal
# # size = len(ds.indexes)
# # loss_dict = defaultdict(lambda : deque(maxlen = 1024))
# loss_logging = deque(maxlen=len(ds) * 3) # this should be configurable parameter, this is 3 * epoch(dataset size)
# # losses = torch.zeros((size,))
# # previous_mean_losses = [0]
# # previous_mean_loss = 0
# # print("Mean loss of {} elements".format(size))
#
# steps_without_grad = 0
#
# last_saved_file = "<none>"
# last_saved_image = "<none>"
# forced_filename = "<none>"
#
# pbar = tqdm.tqdm(total=steps - initial_step)
# try:
# sd_hijack_checkpoint.add()
#
# for _ in range((steps-initial_step) * gradient_step):
# if scheduler.finished:
# break
# if shared.state.interrupted:
# break
# for j, batch in enumerate(dl):
# # works as a drop_last=True for gradient accumulation
# if j == max_steps_per_epoch:
# break
# scheduler.apply(optimizer, hypernetwork.step)
# if scheduler.finished:
# break
# if shared.state.interrupted:
# break
#
# if clip_grad:
# clip_grad_sched.step(hypernetwork.step)
#
# with devices.autocast():
# x = batch.latent_sample.to(devices.device, non_blocking=pin_memory)
# if use_weight:
# w = batch.weight.to(devices.device, non_blocking=pin_memory)
# if tag_drop_out != 0 or shuffle_tags:
# shared.sd_model.cond_stage_model.to(devices.device)
# c = shared.sd_model.cond_stage_model(batch.cond_text).to(devices.device, non_blocking=pin_memory)
# shared.sd_model.cond_stage_model.to(devices.cpu)
# else:
# c = stack_conds(batch.cond).to(devices.device, non_blocking=pin_memory)
# if use_weight:
# loss = shared.sd_model.weighted_forward(x, c, w)[0] / gradient_step
# del w
# else:
# loss = shared.sd_model.forward(x, c)[0] / gradient_step
# del x
# del c
#
# _loss_step += loss.item()
# scaler.scale(loss).backward()
#
# # go back until we reach gradient accumulation steps
# if (j + 1) % gradient_step != 0:
# continue
# loss_logging.append(_loss_step)
# if clip_grad:
# clip_grad(weights, clip_grad_sched.learn_rate)
#
# scaler.step(optimizer)
# scaler.update()
# hypernetwork.step += 1
# pbar.update()
# optimizer.zero_grad(set_to_none=True)
# loss_step = _loss_step
# _loss_step = 0
#
# steps_done = hypernetwork.step + 1
#
# epoch_num = hypernetwork.step // steps_per_epoch
# epoch_step = hypernetwork.step % steps_per_epoch
#
# description = f"Training hypernetwork [Epoch {epoch_num}: {epoch_step+1}/{steps_per_epoch}]loss: {loss_step:.7f}"
# pbar.set_description(description)
# if hypernetwork_dir is not None and steps_done % save_hypernetwork_every == 0:
# # Before saving, change name to match current checkpoint.
# hypernetwork_name_every = f'{hypernetwork_name}-{steps_done}'
# last_saved_file = os.path.join(hypernetwork_dir, f'{hypernetwork_name_every}.pt')
# hypernetwork.optimizer_name = optimizer_name
# if shared.opts.save_optimizer_state:
# hypernetwork.optimizer_state_dict = optimizer.state_dict()
# save_hypernetwork(hypernetwork, checkpoint, hypernetwork_name, last_saved_file)
# hypernetwork.optimizer_state_dict = None # dereference it after saving, to save memory.
#
#
#
# if shared.opts.training_enable_tensorboard:
# epoch_num = hypernetwork.step // len(ds)
# epoch_step = hypernetwork.step - (epoch_num * len(ds)) + 1
# mean_loss = sum(loss_logging) / len(loss_logging)
# textual_inversion.tensorboard_add(tensorboard_writer, loss=mean_loss, global_step=hypernetwork.step, step=epoch_step, learn_rate=scheduler.learn_rate, epoch_num=epoch_num)
#
# textual_inversion.write_loss(log_directory, "hypernetwork_loss.csv", hypernetwork.step, steps_per_epoch, {
# "loss": f"{loss_step:.7f}",
# "learn_rate": scheduler.learn_rate
# })
#
# if images_dir is not None and steps_done % create_image_every == 0:
# forced_filename = f'{hypernetwork_name}-{steps_done}'
# last_saved_image = os.path.join(images_dir, forced_filename)
# hypernetwork.eval()
# rng_state = torch.get_rng_state()
# cuda_rng_state = None
# if torch.cuda.is_available():
# cuda_rng_state = torch.cuda.get_rng_state_all()
# shared.sd_model.cond_stage_model.to(devices.device)
# shared.sd_model.first_stage_model.to(devices.device)
#
# p = processing.StableDiffusionProcessingTxt2Img(
# sd_model=shared.sd_model,
# do_not_save_grid=True,
# do_not_save_samples=True,
# )
#
# p.disable_extra_networks = True
#
# if preview_from_txt2img:
# p.prompt = preview_prompt
# p.negative_prompt = preview_negative_prompt
# p.steps = preview_steps
# p.sampler_name = sd_samplers.samplers_map[preview_sampler_name.lower()]
# p.cfg_scale = preview_cfg_scale
# p.seed = preview_seed
# p.width = preview_width
# p.height = preview_height
# else:
# p.prompt = batch.cond_text[0]
# p.steps = 20
# p.width = training_width
# p.height = training_height
#
# preview_text = p.prompt
#
# with closing(p):
# processed = processing.process_images(p)
# image = processed.images[0] if len(processed.images) > 0 else None
#
# if unload:
# shared.sd_model.cond_stage_model.to(devices.cpu)
# shared.sd_model.first_stage_model.to(devices.cpu)
# torch.set_rng_state(rng_state)
# if torch.cuda.is_available():
# torch.cuda.set_rng_state_all(cuda_rng_state)
# hypernetwork.train()
# if image is not None:
# shared.state.assign_current_image(image)
# if shared.opts.training_enable_tensorboard and shared.opts.training_tensorboard_save_images:
# textual_inversion.tensorboard_add_image(tensorboard_writer,
# f"Validation at epoch {epoch_num}", image,
# hypernetwork.step)
# last_saved_image, last_text_info = images.save_image(image, images_dir, "", p.seed, p.prompt, shared.opts.samples_format, processed.infotexts[0], p=p, forced_filename=forced_filename, save_to_dirs=False)
# last_saved_image += f", prompt: {preview_text}"
#
# shared.state.job_no = hypernetwork.step
#
# shared.state.textinfo = f"""
# <p>
# Loss: {loss_step:.7f}<br/>
# Step: {steps_done}<br/>
# Last prompt: {html.escape(batch.cond_text[0])}<br/>
# Last saved hypernetwork: {html.escape(last_saved_file)}<br/>
# Last saved image: {html.escape(last_saved_image)}<br/>
# </p>
# """
# except Exception:
# errors.report("Exception in training hypernetwork", exc_info=True)
# finally:
# pbar.leave = False
# pbar.close()
# hypernetwork.eval()
# sd_hijack_checkpoint.remove()
#
#
#
# filename = os.path.join(shared.cmd_opts.hypernetwork_dir, f'{hypernetwork_name}.pt')
# hypernetwork.optimizer_name = optimizer_name
# if shared.opts.save_optimizer_state:
# hypernetwork.optimizer_state_dict = optimizer.state_dict()
# save_hypernetwork(hypernetwork, checkpoint, hypernetwork_name, filename)
#
# del optimizer
# hypernetwork.optimizer_state_dict = None # dereference it after saving, to save memory.
# shared.sd_model.cond_stage_model.to(devices.device)
# shared.sd_model.first_stage_model.to(devices.device)
# shared.parallel_processing_allowed = old_parallel_processing_allowed
#
# return hypernetwork, filename
#
# def save_hypernetwork(hypernetwork, checkpoint, hypernetwork_name, filename):
# old_hypernetwork_name = hypernetwork.name
# old_sd_checkpoint = hypernetwork.sd_checkpoint if hasattr(hypernetwork, "sd_checkpoint") else None
# old_sd_checkpoint_name = hypernetwork.sd_checkpoint_name if hasattr(hypernetwork, "sd_checkpoint_name") else None
# try:
# hypernetwork.sd_checkpoint = checkpoint.shorthash
# hypernetwork.sd_checkpoint_name = checkpoint.model_name
# hypernetwork.name = hypernetwork_name
# hypernetwork.save(filename)
# except:
# hypernetwork.sd_checkpoint = old_sd_checkpoint
# hypernetwork.sd_checkpoint_name = old_sd_checkpoint_name
# hypernetwork.name = old_hypernetwork_name
# raise