From 17c95620526302921fb1cac2770f3dba3ebd33a8 Mon Sep 17 00:00:00 2001 From: Imrayya Date: Thu, 14 Sep 2023 15:06:52 +0200 Subject: [PATCH] Updated To actually work --- prompts_from_file_kareeem.py | 405 +++++++++++++++++++---------------- 1 file changed, 221 insertions(+), 184 deletions(-) diff --git a/prompts_from_file_kareeem.py b/prompts_from_file_kareeem.py index 66553e4..634a1d7 100644 --- a/prompts_from_file_kareeem.py +++ b/prompts_from_file_kareeem.py @@ -1,184 +1,221 @@ -import copy -import random -import shlex -import gradio as gr -import modules.scripts as scripts -from modules import sd_samplers, errors, sd_models -from modules.processing import Processed, process_images -from modules.shared import state - -def process_string_tag(tag): - return tag - - -def process_int_tag(tag): - return int(tag) - - -def process_float_tag(tag): - return float(tag) - - -def process_boolean_tag(tag): - return True if (tag == "true") else False - - -prompt_tags = { - "sd_model": None, - "outpath_samples": process_string_tag, - "outpath_grids": process_string_tag, - "prompt_for_display": process_string_tag, - "prompt": process_string_tag, - "negative_prompt": process_string_tag, - "styles": process_string_tag, - "seed": process_int_tag, - "subseed_strength": process_float_tag, - "subseed": process_int_tag, - "seed_resize_from_h": process_int_tag, - "seed_resize_from_w": process_int_tag, - "sampler_index": process_int_tag, - "sampler_name": process_string_tag, - "batch_size": process_int_tag, - "n_iter": process_int_tag, - "steps": process_int_tag, - "cfg_scale": process_float_tag, - "width": process_int_tag, - "height": process_int_tag, - "restore_faces": process_boolean_tag, - "tiling": process_boolean_tag, - "do_not_save_samples": process_boolean_tag, - "do_not_save_grid": process_boolean_tag -} - - -def cmdargs(line, sampler): - args = shlex.split(line) - pos = 0 - res = {} - - while pos < len(args): - arg = args[pos] - - assert arg.startswith("--"), f'must start with "--": {arg}' - assert pos+1 < len(args), f'missing argument for command line option {arg}' - - tag = arg[2:] - - if tag == "prompt" or tag == "negative_prompt": - pos += 1 - prompt = args[pos] - pos += 1 - while pos < len(args) and not args[pos].startswith("--"): - prompt += " " - prompt += args[pos] - pos += 1 - res[tag] = prompt - continue - - - func = prompt_tags.get(tag, None) - assert func, f'unknown commandline option: {arg}' - - val = args[pos+1] - - if tag == "sampler_name": - val = sd_samplers.samplers_map.get(val.lower(), None) - - res[tag] = func(val) - - - pos += 2 - res["sd_model"] = sampler - return res - -def cmdargs(line): - return cmdargs(line, None) - -def load_prompt_file(file): - if file is None: - return None, gr.update(), gr.update(lines=7) - else: - lines = [x.strip() for x in file.decode('utf8', errors='ignore').split("\n")] - return None, "\n".join(lines), gr.update(lines=7) - - -class Script(scripts.Script): - def title(self): - return "Prompts from File Kareem Edition" - - def ui(self, is_img2img): - checkbox_iterate = gr.Checkbox(label="Iterate seed every line", value=False, elem_id=self.elem_id("checkbox_iterate")) - checkbox_iterate_batch = gr.Checkbox(label="Use same random seed for all lines", value=False, elem_id=self.elem_id("checkbox_iterate_batch")) - checkpoint = gr.Dropdown(sorted(sd_models.checkpoints_list),label="Checkpoints", multiselect=True, value=None, lem_id=self.elem_id("checkpoint")) - prompt_txt = gr.Textbox(label="List of prompt inputs", lines=1, elem_id=self.elem_id("prompt_txt")) - file = gr.File(label="Upload prompt inputs", type='binary', elem_id=self.elem_id("file")) - - file.change(fn=load_prompt_file, inputs=[file], outputs=[file, prompt_txt, prompt_txt], show_progress=False) - - # We start at one line. When the text changes, we jump to seven lines, or two lines if no \n. - # We don't shrink back to 1, because that causes the control to ignore [enter], and it may - # be unclear to the user that shift-enter is needed. - prompt_txt.change(lambda tb: gr.update(lines=7) if ("\n" in tb) else gr.update(lines=2), inputs=[prompt_txt], outputs=[prompt_txt], show_progress=False) - return [checkbox_iterate, checkbox_iterate_batch, prompt_txt, checkpoint] - - def run(self, p, checkbox_iterate, checkbox_iterate_batch, prompt_txt: str, checkpoint): - lines = [x.strip() for x in prompt_txt.splitlines()] - lines = [x for x in lines if len(x) > 0] - - job_count = 0 - jobs = [] - if (checkpoint is None): - for line in lines: - if "--" in line: - try: - args = cmdargs(line) - except Exception as e: - errors.display(e, f'parsing prompts: {line}') - args = {"prompt": line} - else: - args = {"prompt": line} - - job_count += args.get("n_iter", p.n_iter) - - jobs.append(args) - else: - for sampler in checkpoint: - for line in lines: - if "--" in line: - try: - args = cmdargs(line, sampler) - except Exception as e: - errors.display(e, f'parsing prompts: {line}') - args = {"prompt": line} - else: - args = {"prompt": line} - - job_count += args.get("n_iter", p.n_iter) - - jobs.append(args) - - print(f"Will process {len(lines)} lines in {job_count} jobs.") - if (checkbox_iterate or checkbox_iterate_batch) and p.seed == -1: - p.seed = int(random.randrange(4294967294)) - - state.job_count = job_count - - images = [] - all_prompts = [] - infotexts = [] - for args in jobs: - state.job = f"{state.job_no + 1} out of {state.job_count}" - - copy_p = copy.copy(p) - for k, v in args.items(): - setattr(copy_p, k, v) - - proc = process_images(copy_p) - images += proc.images - - if checkbox_iterate: - p.seed = p.seed + (p.batch_size * p.n_iter) - all_prompts += proc.all_prompts - infotexts += proc.infotexts - - return Processed(p, images, p.seed, "", all_prompts=all_prompts, infotexts=infotexts) +import copy +import random +import shlex +import gradio as gr +import modules.scripts as scripts +from modules import sd_samplers, errors, sd_models +from modules.processing import Processed, process_images +from modules.shared import state +import modules.shared as shared + + +def process_string_tag(tag): + return tag + + +def process_int_tag(tag): + return int(tag) + + +def process_float_tag(tag): + return float(tag) + + +def process_boolean_tag(tag): + return True if (tag == "true") else False + + +prompt_tags = { + "sd_model": None, + "outpath_samples": process_string_tag, + "outpath_grids": process_string_tag, + "prompt_for_display": process_string_tag, + "prompt": process_string_tag, + "negative_prompt": process_string_tag, + "styles": process_string_tag, + "seed": process_int_tag, + "subseed_strength": process_float_tag, + "subseed": process_int_tag, + "seed_resize_from_h": process_int_tag, + "seed_resize_from_w": process_int_tag, + "sampler_index": process_int_tag, + "sampler_name": process_string_tag, + "batch_size": process_int_tag, + "n_iter": process_int_tag, + "steps": process_int_tag, + "cfg_scale": process_float_tag, + "width": process_int_tag, + "height": process_int_tag, + "restore_faces": process_boolean_tag, + "tiling": process_boolean_tag, + "do_not_save_samples": process_boolean_tag, + "do_not_save_grid": process_boolean_tag +} + + +def sort_checkpoint(checkpoints): + current = shared.opts.sd_model_checkpoint + # print("Debug", current) + # print("Pre Sorted",checkpoints) + if (checkpoints[0] == current): + # print("Already Sorted") + return checkpoints + if (not (current in checkpoints)): + return checkpoints + checkpoints.remove(current) + checkpoints.insert(0, current) + # print("Sorted",checkpoints) + return checkpoints + + +def cmdargs(line, sampler): + args = shlex.split(line) + pos = 0 + res = {} + + while pos < len(args): + arg = args[pos] + + assert arg.startswith("--"), f'must start with "--": {arg}' + assert pos + \ + 1 < len(args), f'missing argument for command line option {arg}' + + tag = arg[2:] + + if tag == "prompt" or tag == "negative_prompt": + pos += 1 + prompt = args[pos] + pos += 1 + while pos < len(args) and not args[pos].startswith("--"): + prompt += " " + prompt += args[pos] + pos += 1 + res[tag] = prompt + continue + + func = prompt_tags.get(tag, None) + assert func, f'unknown commandline option: {arg}' + + val = args[pos+1] + + if tag == "sampler_name": + val = sd_samplers.samplers_map.get(val.lower(), None) + + res[tag] = func(val) + + pos += 2 + if (sampler is not None): + res["sd_model"] = sampler + return res + + +def load_prompt_file(file): + if file is None: + return None, gr.update(), gr.update(lines=7) + else: + lines = [x.strip() for x in file.decode( + 'utf8', errors='ignore').split("\n")] + return None, "\n".join(lines), gr.update(lines=7) + + +def apply_checkpoint(p, x): + if x == shared.opts.sd_model_checkpoint: + return + info = sd_models.get_closet_checkpoint_match(x) + if info is None: + shared.log.warning( + f"XYZ grid: apply checkpoint unknown checkpoint: {x}") + else: + sd_models.reload_model_weights(shared.sd_model, info) + p.override_settings['sd_model_checkpoint'] = info.name + + +class Script(scripts.Script): + def title(self): + return "Prompts from File Kareem Edition" + + def ui(self, is_img2img): + checkbox_iterate = gr.Checkbox( + label="Iterate seed every line", value=False, elem_id=self.elem_id("checkbox_iterate")) + checkbox_iterate_batch = gr.Checkbox( + label="Use same random seed for all lines", value=False, elem_id=self.elem_id("checkbox_iterate_batch")) + checkpoints = gr.Dropdown(sorted(sd_models.checkpoints_list), label="Checkpoints", + multiselect=True, value=None, lem_id=self.elem_id("checkpoints")) + prompt_txt = gr.Textbox( + label="List of prompt inputs", lines=1, elem_id=self.elem_id("prompt_txt")) + file = gr.File(label="Upload prompt inputs", + type='binary', elem_id=self.elem_id("file")) + + file.change(fn=load_prompt_file, inputs=[file], outputs=[ + file, prompt_txt, prompt_txt], show_progress=False) + + # We start at one line. When the text changes, we jump to seven lines, or two lines if no \n. + # We don't shrink back to 1, because that causes the control to ignore [enter], and it may + # be unclear to the user that shift-enter is needed. + prompt_txt.change(lambda tb: gr.update(lines=7) if ("\n" in tb) else gr.update( + lines=2), inputs=[prompt_txt], outputs=[prompt_txt], show_progress=False) + return [checkbox_iterate, checkbox_iterate_batch, prompt_txt, checkpoints] + + def run(self, p, checkbox_iterate, checkbox_iterate_batch, prompt_txt: str, checkpoints): + current = shared.opts.sd_model_checkpoint + lines = [x.strip() for x in prompt_txt.splitlines()] + lines = [x for x in lines if len(x) > 0] + checkpoints = sort_checkpoint(checkpoints) + job_count = 0 + jobs = [] + if (checkpoints is None): + for line in lines: + if "--" in line: + try: + args = cmdargs(line, None) + except Exception as e: + errors.display(e, f'parsing prompts: {line}') + args = {"prompt": line} + else: + args = {"prompt": line} + + job_count += args.get("n_iter", p.n_iter) + + jobs.append(args) + else: + for checkpoint in checkpoints: + for line in lines: + if "--" in line: + try: + args = cmdargs(line, checkpoint) + except Exception as e: + errors.display(e, f'parsing prompts: {line}') + args = {"prompt": line} + else: + args = {"prompt": line, + "sd_model_checkpoint": checkpoint} + + job_count += args.get("n_iter", p.n_iter) + jobs.append(args) + + print(f"Will process {len(lines)} lines in {job_count} jobs.") + if (checkbox_iterate or checkbox_iterate_batch) and p.seed == -1: + p.seed = int(random.randrange(4294967294)) + + state.job_count = job_count + + images = [] + all_prompts = [] + infotexts = [] + for args in jobs: + state.job = f"{state.job_no + 1} out of {state.job_count}" + + copy_p = copy.copy(p) + for k, v in args.items(): + setattr(copy_p, k, v) + if (checkpoints is not None): + apply_checkpoint(copy_p, copy_p.sd_model_checkpoint) + proc = process_images(copy_p) + images += proc.images + + if checkbox_iterate: + p.seed = p.seed + (p.batch_size * p.n_iter) + all_prompts += proc.all_prompts + infotexts += proc.infotexts + apply_checkpoint(copy_p, current) + return Processed(p, images, p.seed, "", all_prompts=all_prompts, infotexts=infotexts)