Updated To actually work

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