"
-
- pbar = tqdm.tqdm(enumerate(ds), total=steps - ititial_step)
- for i, entries in pbar:
- hypernetwork.step = i + ititial_step
- if use_beta_scheduler:
- scheduler_beta.step(hypernetwork.step)
- if len(loss_dict) > 0:
- previous_mean_losses = [i[-1] for i in loss_dict.values()]
- previous_mean_loss = mean(previous_mean_losses)
- if not use_beta_scheduler:
- scheduler.apply(optimizer, hypernetwork.step)
- if i + ititial_step > steps:
- break
-
- if shared.state.interrupted:
- break
-
- with torch.autocast("cuda"):
- c = stack_conds([entry.cond for entry in entries]).to(devices.device)
- # c = torch.vstack([entry.cond for entry in entries]).to(devices.device)
- x = torch.stack([entry.latent for entry in entries]).to(devices.device)
- loss_infos = shared.sd_model(x, c)[1]
- loss = loss_infos[
- 'val/loss_simple'] # + loss_infos['val/loss_vlb'] * 0.4 #its 'prior class preserving' loss
- del x
- del c
-
- losses[hypernetwork.step % losses.shape[0]] = loss.item()
- losses_list.append(loss.item())
- for entry in entries:
- loss_dict[entry.filename].append(loss.item())
- optimizer.zero_grad()
- weights[0].grad = None
- loss.backward()
-
- if weights[0].grad is None:
- steps_without_grad += 1
- else:
- steps_without_grad = 0
- assert steps_without_grad < 10, 'no gradient found for the trained weight after backward() for 10 steps in a row; this is a bug; training cannot continue'
- optimizer.step()
-
- steps_done = hypernetwork.step + 1
-
- if torch.isnan(losses[hypernetwork.step % losses.shape[0]]):
- raise RuntimeError("Loss diverged.")
-
- if len(previous_mean_losses) > 1:
- std = stdev(previous_mean_losses)
- else:
- std = 0
- dataset_loss_info = f"dataset loss:{mean(previous_mean_losses):.3f}" + u"\u00B1" + f"({std / (len(previous_mean_losses) ** 0.5):.3f})"
- pbar.set_description(dataset_loss_info)
-
- 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.
-
- textual_inversion.write_loss(log_directory, "hypernetwork_loss.csv", hypernetwork.step, len(ds), {
- "loss": f"{previous_mean_loss:.7f}",
- "learn_rate": optimizer.param_groups[0]['lr']
- })
-
- 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)
- optimizer.zero_grad()
- optim_to(optimizer, devices.cpu)
- 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,
- )
-
- if preview_from_txt2img:
- p.prompt = preview_prompt
- p.negative_prompt = preview_negative_prompt
- p.steps = preview_steps
- p.sampler_name = sd_samplers.samplers[preview_sampler_index].name
- p.cfg_scale = preview_cfg_scale
- p.seed = preview_seed
- p.width = preview_width
- p.height = preview_height
- else:
- p.prompt = entries[0].cond_text
- p.steps = 20
-
- preview_text = p.prompt
-
- 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)
-
- if image is not None:
- shared.state.current_image = image
- 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}"
- optim_to(optimizer, devices.device)
-
- shared.state.job_no = hypernetwork.step
-
- shared.state.textinfo = f"""
-
-Loss: {previous_mean_loss:.7f}
-Step: {hypernetwork.step}
-Last prompt: {html.escape(entries[0].cond_text)}
-Last saved hypernetwork: {html.escape(last_saved_file)}
-Last saved image: {html.escape(last_saved_image)}
-
-"""
-
- report_statistics(loss_dict)
-
- 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.
- hypernetwork.eval()
- return hypernetwork, filename
def apply_strength(value=None):
HypernetworkModule.multiplier = value if value is not None else shared.opts.sd_hypernetwork_strength
+
def apply_hypernetwork_strength(p, x, xs):
apply_strength(x)
+
def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments=None, iteration=0, position_in_batch=0):
index = position_in_batch + iteration * p.batch_size
@@ -778,9 +566,6 @@ def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments=None, iter
"Size": f"{p.width}x{p.height}",
"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),
"Model": (None if not opts.add_model_name_to_info or not shared.sd_model.sd_checkpoint_info.model_name else shared.sd_model.sd_checkpoint_info.model_name.replace(',', '').replace(':', '')),
- "Hypernet": (None if shared.loaded_hypernetwork is None or not hasattr(shared.loaded_hypernetwork, 'name') else shared.loaded_hypernetwork.name),
- "Hypernet hash": (None if shared.loaded_hypernetwork is None or not hasattr(shared.loaded_hypernetwork, 'filename') else sd_models.model_hash(shared.loaded_hypernetwork.filename)),
- "Hypernet strength": (None if shared.loaded_hypernetwork is None or shared.opts.sd_hypernetwork_strength >= 1 else shared.opts.sd_hypernetwork_strength),
"Batch size": (None if p.batch_size < 2 else p.batch_size),
"Batch pos": (None if p.batch_size < 2 else position_in_batch),
"Variation seed": (None if p.subseed_strength == 0 else all_subseeds[index]),
@@ -801,13 +586,19 @@ def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments=None, iter
return f"{all_prompts[index]}{negative_prompt_text}\n{generation_params_text}".strip()
+
modules.hypernetworks.hypernetwork.list_hypernetworks = list_hypernetworks
modules.hypernetworks.hypernetwork.load_hypernetwork = load_hypernetwork
-modules.hypernetworks.hypernetwork.apply_hypernetwork = apply_hypernetwork
-modules.hypernetworks.hypernetwork.apply_strength = apply_strength
+if hasattr(modules.hypernetworks.hypernetwork, 'apply_hypernetwork'):
+ modules.hypernetworks.hypernetwork.apply_hypernetwork = apply_hypernetwork
+else:
+ modules.hypernetworks.hypernetwork.apply_single_hypernetwork = apply_single_hypernetwork
+if hasattr(modules.hypernetworks.hypernetwork, 'apply_strength'):
+ modules.hypernetworks.hypernetwork.apply_strength = apply_strength
modules.hypernetworks.hypernetwork.Hypernetwork = Hypernetwork
modules.hypernetworks.hypernetwork.HypernetworkModule = HypernetworkModule
-scripts.xy_grid.apply_hypernetwork_strength = apply_hypernetwork_strength
+if hasattr(scripts.xy_grid, 'apply_hypernetwork_strength'):
+ scripts.xy_grid.apply_hypernetwork_strength = apply_hypernetwork_strength
# Fix calculating hash for multiple hns
processing.create_infotext = create_infotext
\ No newline at end of file
diff --git a/patches/hypernetworks.py b/patches/hypernetworks.py
index a9b5fd9..32110c9 100644
--- a/patches/hypernetworks.py
+++ b/patches/hypernetworks.py
@@ -4,6 +4,8 @@ import os.path
import torch
from modules import devices, shared
+from .hnutil import find_self
+from .shared import version_flag
lazy_load = False # when this is enabled, HNs will be loaded when required.
@@ -79,6 +81,17 @@ class Forward:
def __call__(self, *args, **kwargs):
raise NotImplementedError
+ def set_multiplier(self, *args, **kwargs):
+ pass
+
+ def extra_name(self):
+ if version_flag:
+ return ""
+ found = find_self(self)
+ if found is not None:
+ return f" "
+ return f" "
+
@staticmethod
def parse(arg, name=None):
arg = Forward.unpack(arg)
diff --git a/patches/shared.py b/patches/shared.py
index a407b8d..457bfe2 100644
--- a/patches/shared.py
+++ b/patches/shared.py
@@ -2,11 +2,13 @@
from modules.shared import cmd_opts, opts
import modules.shared
+version_flag = hasattr(modules.shared, 'loaded_hypernetwork')
def reload_hypernetworks():
from .hypernetwork import list_hypernetworks, load_hypernetwork
modules.shared.hypernetworks = list_hypernetworks(cmd_opts.hypernetwork_dir)
- load_hypernetwork(opts.sd_hypernetwork)
+ if hasattr(modules.shared, 'loaded_hypernetwork'):
+ load_hypernetwork(opts.sd_hypernetwork)
try:
diff --git a/patches/ui.py b/patches/ui.py
index 3c1659c..be1b86b 100644
--- a/patches/ui.py
+++ b/patches/ui.py
@@ -1,8 +1,8 @@
-import html
import os
-from modules import shared, sd_hijack, devices
-from .hypernetwork import Hypernetwork, train_hypernetwork, load_hypernetwork
+from modules import shared
+from .hypernetwork import Hypernetwork, load_hypernetwork
+
def create_hypernetwork_load(name, enable_sizes, overwrite_old, layer_structure=None, activation_func=None, weight_init=None, add_layer_norm=False, use_dropout=False, dropout_structure=None, optional_info=None,
weight_init_seed=None, normal_std=0.01, skip_connection=False):
@@ -36,8 +36,8 @@ def create_hypernetwork_load(name, enable_sizes, overwrite_old, layer_structure=
)
hypernet.save(fn)
shared.reload_hypernetworks()
- load_hypernetwork(fn)
-
+ hypernet = load_hypernetwork(name)
+ assert hypernet is not None, f"Cannot load from {name}!"
return hypernet
@@ -76,27 +76,3 @@ def create_hypernetwork(name, enable_sizes, overwrite_old, layer_structure=None,
shared.reload_hypernetworks()
return name, f"Created: {fn}", ""
-
-def train_hypernetwork_ui(*args):
-
- initial_hypernetwork = shared.loaded_hypernetwork
-
- assert not shared.cmd_opts.lowvram, 'Training models with lowvram is not possible'
-
- try:
- sd_hijack.undo_optimizations()
-
- hypernetwork, filename = train_hypernetwork(*args)
-
- res = f"""
-Training {'interrupted' if shared.state.interrupted else 'finished'} at {hypernetwork.step} steps.
-Hypernetwork saved to {html.escape(filename)}
-"""
- return res, ""
- except Exception:
- raise
- finally:
- shared.loaded_hypernetwork = initial_hypernetwork
- shared.sd_model.cond_stage_model.to(devices.device)
- shared.sd_model.first_stage_model.to(devices.device)
- sd_hijack.apply_optimizations()
\ No newline at end of file
diff --git a/scripts/hypernetwork-extensions.py b/scripts/hypernetwork-extensions.py
index 713472b..17a954a 100644
--- a/scripts/hypernetwork-extensions.py
+++ b/scripts/hypernetwork-extensions.py
@@ -17,95 +17,6 @@ from webui import wrap_gradio_gpu_call
setattr(shared.opts,'pin_memory', False)
-
-def create_training_tab(params: script_callbacks.UiTrainTabParams = None):
- with gr.Tab(label="Train_Beta") as train_beta:
- gr.HTML(
- value="Train an embedding or Hypernetwork; you must specify a directory with a set of 1:1 ratio images [wiki]
")
- with gr.Row():
- train_hypernetwork_name = gr.Dropdown(label='Hypernetwork', elem_id="train_hypernetwork",
- choices=[x for x in shared.hypernetworks.keys()])
- create_refresh_button(train_hypernetwork_name, shared.reload_hypernetworks,
- lambda: {"choices": sorted([x for x in shared.hypernetworks.keys()])},
- "refresh_train_hypernetwork_name")
- with gr.Row():
- hypernetwork_learn_rate = gr.Textbox(label='Hypernetwork Learning rate',
- placeholder="Hypernetwork Learning rate", value="0.00001")
- use_beta_scheduler_checkbox = gr.Checkbox(
- label='Show advanced learn rate scheduler options(for Hypernetworks)')
- with gr.Row(visible=False) as beta_scheduler_options:
- use_beta_scheduler = gr.Checkbox(label='Uses CosineAnnealingWarmRestarts Scheduler')
- beta_repeat_epoch = gr.Textbox(label='Epoch for cycle', placeholder="Cycles every nth epoch", value="4000")
- epoch_mult = gr.Textbox(label='Epoch multiplier per cycle', placeholder="Cycles length multiplier every cycle", value="1")
- warmup = gr.Textbox(label='Warmup step per cycle', placeholder="CosineAnnealing lr increase step", value="1")
- min_lr = gr.Textbox(label='Minimum learning rate for beta scheduler',
- placeholder="restricts decay value, but does not restrict gamma rate decay",
- value="1e-7")
- gamma_rate = gr.Textbox(label='Separate learning rate decay for ExponentialLR',
- placeholder="Value should be in (0-1]", value="1")
- batch_size = gr.Number(label='Batch size', value=1, precision=0)
- dataset_directory = gr.Textbox(label='Dataset directory', placeholder="Path to directory with input images")
- log_directory = gr.Textbox(label='Log directory', placeholder="Path to directory where to write outputs",
- value="textual_inversion")
- template_file = gr.Textbox(label='Prompt template file',
- value=os.path.join(script_path, "textual_inversion_templates",
- "style_filewords.txt"))
- training_width = gr.Slider(minimum=64, maximum=2048, step=64, label="Width", value=512)
- training_height = gr.Slider(minimum=64, maximum=2048, step=64, label="Height", value=512)
- steps = gr.Number(label='Max steps', value=100000, precision=0)
- create_image_every = gr.Number(label='Save an image to log directory every N steps, 0 to disable', value=500,
- precision=0)
- save_embedding_every = gr.Number(label='Save a copy of embedding to log directory every N steps, 0 to disable',
- value=500, precision=0)
- preview_from_txt2img = gr.Checkbox(
- label='Read parameters (prompt, etc...) from txt2img tab when making previews', value=False)
-
- with gr.Row():
- interrupt_training = gr.Button(value="Interrupt")
- train_hypernetwork = gr.Button(value="Train Hypernetwork", variant='primary')
- ti_output = gr.Text(elem_id="ti_output2", value="", show_label=False)
- ti_outcome = gr.HTML(elem_id="ti_error2", value="")
- use_beta_scheduler_checkbox.change(
- fn=lambda show: gr_show(show),
- inputs=[use_beta_scheduler_checkbox],
- outputs=[beta_scheduler_options],
- )
- interrupt_training.click(
- fn=lambda: shared.state.interrupt(),
- inputs=[],
- outputs=[],
- )
- train_hypernetwork.click(
- fn=wrap_gradio_gpu_call(ui.train_hypernetwork_ui, extra_outputs=[gr.update()]),
- _js="start_training_textual_inversion",
- inputs=[
- train_hypernetwork_name,
- hypernetwork_learn_rate,
- batch_size,
- dataset_directory,
- log_directory,
- training_width,
- training_height,
- steps,
- create_image_every,
- save_embedding_every,
- template_file,
- preview_from_txt2img,
- *params.txt2img_preview_params,
- use_beta_scheduler,
- beta_repeat_epoch,
- epoch_mult,
- warmup,
- min_lr,
- gamma_rate
- ],
- outputs=[
- ti_output,
- ti_outcome,
- ]
- )
- return [(train_beta, "Train_beta", "train_beta")]
-
def create_extension_tab(params=None):
with gr.Tab(label="Create Beta hypernetwork") as create_beta:
new_hypernetwork_name = gr.Textbox(label="Name")