mirror of
https://github.com/vladmandic/automatic
synced 2026-09-20 01:31:13 +02:00
correct metadata before/after
This commit is contained in:
@@ -81,7 +81,7 @@ svg.feather.feather-image, .feather .feather-image { display: none }
|
||||
#quicksettings .gr-button-tool { font-size: 1.6rem; box-shadow: none; margin-left: -20px; margin-top: -2px; height: 2.4em; }
|
||||
#quicksettings > div, #quicksettings > fieldset { min-width: 26em; max-width: 26em; line-height: 2em; }
|
||||
#refresh_sd_model_checkpoint { height: 48px; margin-left: -14px; background: #333333; box-shadow: none; }
|
||||
#refresh_txt2img_styles, #refresh_img2img_styles, #open_folder_txt2img, #open_folder_img2img, #open_folder_extras, #footer, #style_pos_col, #style_neg_col, #roll_col, #extras_upscaler_2, #extras_upscaler_2_visibility, #txt2img_res_switch_btn, #img2img_res_switch_btn, #txt2img_seed_resize_from_w, #txt2img_seed_resize_from_h, #txt2img_tiling { display: none; }
|
||||
#refresh_txt2img_styles, #refresh_img2img_styles, #open_folder_txt2img, #open_folder_img2img, #open_folder_extras, #footer, #style_pos_col, #style_neg_col, #roll_col, #extras_upscaler_2, #extras_upscaler_2_visibility, #txt2img_res_switch_btn, #img2img_res_switch_btn, #txt2img_seed_resize_from_w, #txt2img_seed_resize_from_h { display: none; }
|
||||
#save-animation { border-radius: 0 !important; margin-bottom: 16px; background-color: #111111; }
|
||||
#script_list { padding: 4px; margin-top: 20px; margin-bottom: 20px; }
|
||||
#settings > div.flex-wrap { width: 15em; }
|
||||
|
||||
@@ -15,18 +15,14 @@ from modules import shared, images, sd_models, sd_vae, sd_models_config
|
||||
def run_pnginfo(image):
|
||||
if image is None:
|
||||
return '', '', ''
|
||||
|
||||
geninfo, items = images.read_info_from_image(image)
|
||||
items = {**{'parameters': geninfo}, **items}
|
||||
|
||||
info = ''
|
||||
for key, text in items.items():
|
||||
info += f"<div><b>{html.escape(str(key))}</b>: {html.escape(str(text))}</div>"
|
||||
|
||||
if len(info) == 0:
|
||||
message = "Nothing found in the image."
|
||||
info = f"<div><p>{message}<p></div>"
|
||||
|
||||
return '', geninfo, info
|
||||
|
||||
|
||||
@@ -43,13 +39,10 @@ def create_config(ckpt_result, config_source, a, b, c):
|
||||
cfg = config(c)
|
||||
else:
|
||||
cfg = None
|
||||
|
||||
if cfg is None:
|
||||
return
|
||||
|
||||
filename, _ = os.path.splitext(ckpt_result)
|
||||
checkpoint_filename = filename + ".yaml"
|
||||
|
||||
shared.log.info("Copying config: {cfg} -> {checkpoint_filename}")
|
||||
shutil.copyfile(cfg, checkpoint_filename)
|
||||
|
||||
@@ -60,7 +53,6 @@ checkpoint_dict_skip_on_merge = ["cond_stage_model.transformer.text_model.embedd
|
||||
def to_half(tensor, enable):
|
||||
if enable and tensor.dtype == torch.float:
|
||||
return tensor.half()
|
||||
|
||||
return tensor
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ from modules.memstats import memory_stats
|
||||
|
||||
|
||||
def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args):
|
||||
shared.log.debug(f'batch: {input_dir}|{output_dir}|{inpaint_mask_dir}')
|
||||
processing.fix_seed(p)
|
||||
images = shared.listfiles(input_dir)
|
||||
is_inpaint_batch = False
|
||||
@@ -68,6 +69,7 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s
|
||||
if shared.sd_model is None:
|
||||
shared.log.warning('Model not loaded')
|
||||
return
|
||||
shared.log.debug(f'img2img: {id_task}|{mode}|{prompt}|{negative_prompt}|{prompt_styles}|{init_img}|{sketch}|{init_img_with_mask}|{inpaint_color_sketch}|{inpaint_color_sketch_orig}|{init_img_inpaint}|{init_mask_inpaint}|{steps}|{sampler_index}|{mask_blur}|{mask_alpha}|{inpainting_fill}|{restore_faces}|{tiling}|{n_iter}|{batch_size}|{cfg_scale}|{image_cfg_scale}|{denoising_strength}|{seed}|{subseed}|{subseed_strength}|{seed_resize_from_h}|{seed_resize_from_w}|{seed_enable_extras}|{selected_scale_tab}|{height}|{width}|{scale_by}|{resize_mode}|{inpaint_full_res}|{inpaint_full_res_padding}|{inpainting_mask_invert}|{img2img_batch_input_dir}|{img2img_batch_output_dir}|{img2img_batch_inpaint_mask_dir}|{override_settings_texts}')
|
||||
|
||||
override_settings = create_override_settings_dict(override_settings_texts)
|
||||
|
||||
|
||||
+16
-51
@@ -449,7 +449,6 @@ def fix_seed(p):
|
||||
|
||||
def create_infotext(p: StableDiffusionProcessing, all_prompts, all_seeds, all_subseeds, comments=None, iteration=0, position_in_batch=0): # pylint: disable=unused-argument
|
||||
index = position_in_batch + iteration * p.batch_size
|
||||
|
||||
generation_params = {
|
||||
"Steps": p.steps,
|
||||
"Sampler": p.sampler_name,
|
||||
@@ -479,11 +478,8 @@ def create_infotext(p: StableDiffusionProcessing, all_prompts, all_seeds, all_su
|
||||
"Token merging stride y": None if opts.token_merging_stride_y == 2 else opts.token_merging_stride_y
|
||||
}
|
||||
generation_params.update(p.extra_generation_params)
|
||||
|
||||
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])
|
||||
|
||||
negative_prompt_text = "\nNegative prompt: " + p.all_negative_prompts[index] if p.all_negative_prompts[index] else ""
|
||||
|
||||
return f"{all_prompts[index]}{negative_prompt_text}\n{generation_params_text}".strip()
|
||||
|
||||
|
||||
@@ -542,17 +538,12 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
assert len(p.prompt) > 0
|
||||
else:
|
||||
assert p.prompt is not None
|
||||
|
||||
devices.torch_gc()
|
||||
|
||||
seed = get_fixed_seed(p.seed)
|
||||
subseed = get_fixed_seed(p.subseed)
|
||||
|
||||
modules.sd_hijack.model_hijack.apply_circular(p.tiling)
|
||||
modules.sd_hijack.model_hijack.clear_comments()
|
||||
|
||||
comments = {}
|
||||
|
||||
if type(p.prompt) == list:
|
||||
p.all_prompts = [shared.prompt_styles.apply_styles_to_prompt(x, p.styles) for x in p.prompt]
|
||||
else:
|
||||
@@ -562,12 +553,10 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
p.all_negative_prompts = [shared.prompt_styles.apply_negative_styles_to_prompt(x, p.styles) for x in p.negative_prompt]
|
||||
else:
|
||||
p.all_negative_prompts = p.batch_size * p.n_iter * [shared.prompt_styles.apply_negative_styles_to_prompt(p.negative_prompt, p.styles)]
|
||||
|
||||
if type(seed) == list:
|
||||
p.all_seeds = seed
|
||||
else:
|
||||
p.all_seeds = [int(seed) + (x if p.subseed_strength == 0 else 0) for x in range(len(p.all_prompts))]
|
||||
|
||||
if type(subseed) == list:
|
||||
p.all_subseeds = subseed
|
||||
else:
|
||||
@@ -578,13 +567,10 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
|
||||
if os.path.exists(opts.embeddings_dir) and not p.do_not_reload_embeddings:
|
||||
model_hijack.embedding_db.load_textual_inversion_embeddings()
|
||||
|
||||
if p.scripts is not None:
|
||||
p.scripts.process(p)
|
||||
|
||||
infotexts = []
|
||||
output_images = []
|
||||
|
||||
cached_uc = [None, None]
|
||||
cached_c = [None, None]
|
||||
|
||||
@@ -598,13 +584,10 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
have been used before. The second element is where the previously
|
||||
computed result is stored.
|
||||
"""
|
||||
|
||||
if cache[0] is not None and (required_prompts, steps) == cache[0]:
|
||||
return cache[1]
|
||||
|
||||
with devices.autocast():
|
||||
cache[1] = function(shared.sd_model, required_prompts, steps)
|
||||
|
||||
cache[0] = (required_prompts, steps)
|
||||
return cache[1]
|
||||
|
||||
@@ -613,49 +596,33 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
p.init(p.all_prompts, p.all_seeds, p.all_subseeds)
|
||||
if shared.opts.live_previews_enable and opts.show_progress_type == "Approx NN":
|
||||
sd_vae_approx.model()
|
||||
|
||||
if state.job_count == -1:
|
||||
state.job_count = p.n_iter
|
||||
|
||||
extra_network_data = None
|
||||
for n in range(p.n_iter):
|
||||
p.iteration = n
|
||||
|
||||
if state.skipped:
|
||||
state.skipped = False
|
||||
|
||||
if state.interrupted:
|
||||
break
|
||||
|
||||
prompts = p.all_prompts[n * p.batch_size:(n + 1) * p.batch_size]
|
||||
negative_prompts = p.all_negative_prompts[n * p.batch_size:(n + 1) * p.batch_size]
|
||||
seeds = p.all_seeds[n * p.batch_size:(n + 1) * p.batch_size]
|
||||
subseeds = p.all_subseeds[n * p.batch_size:(n + 1) * p.batch_size]
|
||||
|
||||
if p.scripts is not None:
|
||||
p.scripts.before_process_batch(p, batch_number=n, prompts=prompts, seeds=seeds, subseeds=subseeds)
|
||||
|
||||
if len(prompts) == 0:
|
||||
break
|
||||
|
||||
prompts, extra_network_data = extra_networks.parse_prompts(prompts)
|
||||
|
||||
if not p.disable_extra_networks:
|
||||
with devices.autocast():
|
||||
extra_networks.activate(p, extra_network_data)
|
||||
|
||||
if p.scripts is not None:
|
||||
p.scripts.process_batch(p, batch_number=n, prompts=prompts, seeds=seeds, subseeds=subseeds)
|
||||
|
||||
# params.txt should be saved after scripts.process_batch, since the
|
||||
# infotext could be modified by that callback
|
||||
# Example: a wildcard processed by process_batch sets an extra model
|
||||
# strength, which is saved as "Model Strength: 1.0" in the infotext
|
||||
if n == 0:
|
||||
with open(os.path.join(paths.data_path, "params.txt"), "w", encoding="utf8") as file:
|
||||
processed = Processed(p, [], p.seed, "")
|
||||
file.write(processed.infotext(p, 0))
|
||||
|
||||
step_multiplier = 1
|
||||
if not shared.opts.dont_fix_second_order_samplers_schedule:
|
||||
try:
|
||||
@@ -664,17 +631,13 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
pass
|
||||
uc = get_conds_with_caching(prompt_parser.get_learned_conditioning, negative_prompts, p.steps * step_multiplier, cached_uc)
|
||||
c = get_conds_with_caching(prompt_parser.get_multicond_learned_conditioning, prompts, p.steps * step_multiplier, cached_c)
|
||||
|
||||
if len(model_hijack.comments) > 0:
|
||||
for comment in model_hijack.comments:
|
||||
comments[comment] = 1
|
||||
|
||||
if p.n_iter > 1:
|
||||
shared.state.job = f"Batch {n+1} out of {p.n_iter}"
|
||||
|
||||
with devices.without_autocast() if devices.unet_needs_upcast else devices.autocast():
|
||||
samples_ddim = p.sample(conditioning=c, unconditional_conditioning=uc, seeds=seeds, subseeds=subseeds, subseed_strength=p.subseed_strength, prompts=prompts)
|
||||
|
||||
x_samples_ddim = [decode_first_stage(p.sd_model, samples_ddim[i:i+1].to(dtype=devices.dtype_vae))[0].cpu() for i in range(samples_ddim.size(0))]
|
||||
try:
|
||||
for x in x_samples_ddim:
|
||||
@@ -690,45 +653,41 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
||||
devices.test_for_nans(x, "vae")
|
||||
else:
|
||||
raise e
|
||||
|
||||
x_samples_ddim = torch.stack(x_samples_ddim).float()
|
||||
x_samples_ddim = torch.clamp((x_samples_ddim + 1.0) / 2.0, min=0.0, max=1.0)
|
||||
|
||||
del samples_ddim
|
||||
|
||||
if shared.cmd_opts.lowvram or shared.cmd_opts.medvram:
|
||||
lowvram.send_everything_to_cpu()
|
||||
|
||||
devices.torch_gc()
|
||||
|
||||
if p.scripts is not None:
|
||||
p.scripts.postprocess_batch(p, x_samples_ddim, batch_number=n)
|
||||
|
||||
for i, x_sample in enumerate(x_samples_ddim):
|
||||
p.batch_index = i
|
||||
x_sample = 255. * np.moveaxis(x_sample.cpu().numpy(), 0, 2)
|
||||
x_sample = x_sample.astype(np.uint8)
|
||||
|
||||
if p.restore_faces:
|
||||
if opts.save and not p.do_not_save_samples and opts.save_images_before_face_restoration:
|
||||
images.save_image(Image.fromarray(x_sample), p.outpath_samples, "", seeds[i], prompts[i], opts.samples_format, info=infotext(n, i), p=p, suffix="-before-face-restoration")
|
||||
|
||||
orig = p.restore_faces
|
||||
p.restore_faces = False
|
||||
info=infotext(n, i)
|
||||
p.restore_faces = orig
|
||||
images.save_image(Image.fromarray(x_sample), p.outpath_samples, "", seeds[i], prompts[i], opts.samples_format, info=info, p=p, suffix="-before-face-restoration")
|
||||
devices.torch_gc()
|
||||
|
||||
x_sample = modules.face_restoration.restore_faces(x_sample)
|
||||
devices.torch_gc()
|
||||
|
||||
image = Image.fromarray(x_sample)
|
||||
|
||||
if p.scripts is not None:
|
||||
pp = scripts.PostprocessImageArgs(image)
|
||||
p.scripts.postprocess_image(p, pp)
|
||||
image = pp.image
|
||||
|
||||
if p.color_corrections is not None and i < len(p.color_corrections):
|
||||
if opts.save and not p.do_not_save_samples and opts.save_images_before_color_correction:
|
||||
orig = p.color_corrections
|
||||
p.color_corrections = None
|
||||
info=infotext(n, i)
|
||||
p.color_corrections = orig
|
||||
image_without_cc = apply_overlay(image, p.paste_to, i, p.overlay_images)
|
||||
images.save_image(image_without_cc, p.outpath_samples, "", seeds[i], prompts[i], opts.samples_format, info=infotext(n, i), p=p, suffix="-before-color-correction")
|
||||
images.save_image(image_without_cc, p.outpath_samples, "", seeds[i], prompts[i], opts.samples_format, info=info, p=p, suffix="-before-color-correction")
|
||||
image = apply_color_correction(p.color_corrections[i], image)
|
||||
image = apply_overlay(image, p.paste_to, i, p.overlay_images)
|
||||
if opts.samples_save and not p.do_not_save_samples:
|
||||
@@ -878,7 +837,13 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
|
||||
return
|
||||
if not isinstance(image, Image.Image):
|
||||
image = sd_samplers.sample_to_image(image, index, approximation=0)
|
||||
orig1 = self.extra_generation_params
|
||||
orig2 = self.restore_faces
|
||||
self.extra_generation_params = {}
|
||||
self.restore_faces = False
|
||||
info = create_infotext(self, self.all_prompts, self.all_seeds, self.all_subseeds, [], iteration=self.iteration, position_in_batch=index)
|
||||
self.extra_generation_params = orig1
|
||||
self.restore_faces = orig2
|
||||
images.save_image(image, self.outpath_samples, "", seeds[index], prompts[index], opts.samples_format, info=info, suffix="-before-highres-fix")
|
||||
|
||||
if latent_scale_mode is not None:
|
||||
|
||||
@@ -8,9 +8,12 @@ from modules.memstats import memory_stats
|
||||
|
||||
|
||||
def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, steps: int, sampler_index: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, enable_hr: bool, denoising_strength: float, hr_scale: float, hr_upscaler: str, hr_second_pass_steps: int, hr_resize_x: int, hr_resize_y: int, override_settings_texts, *args): # pylint: disable=unused-argument
|
||||
|
||||
if shared.sd_model is None:
|
||||
shared.log.warning('Model not loaded')
|
||||
return
|
||||
shared.log.debug(f'txt2img: {id_task}|{prompt}|{negative_prompt}|{prompt_styles}|{steps}|{sampler_index}|{restore_faces}|{tiling}|{n_iter}|{batch_size}|{cfg_scale}|{seed}|{subseed}|{subseed_strength}|{seed_resize_from_h}|{seed_resize_from_w}|{seed_enable_extras}|{height}|{width}|{enable_hr}|{denoising_strength}|{hr_scale}|{hr_upscaler}|{hr_second_pass_steps}|{hr_resize_x}|{hr_resize_y}|{override_settings_texts}')
|
||||
|
||||
override_settings = create_override_settings_dict(override_settings_texts)
|
||||
p = StableDiffusionProcessingTxt2Img(
|
||||
sd_model=shared.sd_model,
|
||||
|
||||
@@ -50,6 +50,7 @@ class Upscaler:
|
||||
return img
|
||||
|
||||
def upscale(self, img: PIL.Image, scale, selected_model: str = None):
|
||||
shared.log.debug(f'upscale: {img}|{scale}|{selected_model}')
|
||||
self.scale = scale
|
||||
dest_w = int(img.width * scale)
|
||||
dest_h = int(img.height * scale)
|
||||
|
||||
Reference in New Issue
Block a user