|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import sys |
|
|
|
import os.path |
|
|
|
import json |
|
|
|
import gc |
|
|
|
import functools |
|
|
|
import argparse |
|
|
|
import numpy |
|
|
|
|
|
from PIL import Image, PngImagePlugin |
|
|
|
|
|
from diffusers import OnnxStableDiffusionPipeline, OnnxStableDiffusionImg2ImgPipeline |
|
from pipeline_onnx_stable_diffusion_controlnet import OnnxStableDiffusionControlNetPipeline |
|
|
|
from diffusers import OnnxRuntimeModel |
|
|
|
from diffusers import ( |
|
DDIMScheduler, |
|
DEISMultistepScheduler, |
|
DPMSolverMultistepScheduler, |
|
DPMSolverSinglestepScheduler, |
|
EulerAncestralDiscreteScheduler, |
|
EulerDiscreteScheduler, |
|
HeunDiscreteScheduler, |
|
KDPM2DiscreteScheduler, |
|
LMSDiscreteScheduler, |
|
PNDMScheduler, |
|
UniPCMultistepScheduler |
|
) |
|
|
|
|
|
import OnnxDiffusersUI.lpw_pipe |
|
|
|
|
|
defSettings = { |
|
"width": 512, |
|
"height": 512, |
|
"reslist": [], |
|
"steps": 30, |
|
"stepslist": [], |
|
"scale": 7.5, |
|
"scalelist":[], |
|
"seed":0, |
|
"seedend":0, |
|
"seedlist":[], |
|
"task": "txt2img", |
|
"model":"sd2_1-fp16", |
|
"prompt": "", |
|
"promptlist":[], |
|
"negative_prompt": "", |
|
"textenc": "standard", |
|
"scheduler": "pndm", |
|
"schedulerlist": [], |
|
"strength": 0.9, |
|
"strengthlist": [] |
|
} |
|
|
|
parser = argparse.ArgumentParser() |
|
|
|
parser.add_argument( |
|
"--cpu-textenc", |
|
action="store_true", |
|
help="Load Text Encoder on CPU to save VRAM" |
|
) |
|
|
|
parser.add_argument( |
|
"--subdirs", |
|
action="store_true", |
|
help="Add subdirs with settings.json to projects to run" |
|
) |
|
|
|
parser.add_argument( |
|
'project', |
|
nargs='+', |
|
type=str, |
|
help="Provide projects as directories that contain settings.json" |
|
) |
|
|
|
args = parser.parse_args() |
|
|
|
projects=args.project |
|
if args.subdirs: |
|
for proj in args.project: |
|
obj = os.scandir(proj) |
|
for entry in obj: |
|
if entry.is_dir(): |
|
if os.path.isfile(f"{proj}/{entry.name}/settings.json"): |
|
projects.append(f"{proj}/{entry.name}") |
|
|
|
for proj in projects: |
|
print("Running project "+proj) |
|
|
|
if os.path.isdir(proj): |
|
if os.path.isfile(proj+"/settings.json"): |
|
with open(proj+"/settings.json", encoding="utf-8") as confFile: |
|
projSettings=json.load(confFile) |
|
|
|
runSettings = defSettings | projSettings |
|
|
|
prereqmet=len(runSettings['prompt'])>0 or len(runSettings['promptlist'])>0 |
|
|
|
model="model/"+runSettings['model'] |
|
prereqmet=prereqmet and os.path.isfile(model+"/unet/model.onnx") |
|
|
|
if runSettings['task']=="img2img" or runSettings['task']=="controlnet": |
|
infile=proj+"/input.png" |
|
prereqmet = prereqmet and os.path.isfile(infile) |
|
if prereqmet: |
|
sched = { |
|
"ddim": DDIMScheduler.from_pretrained(model, subfolder="scheduler"), |
|
"deis": DEISMultistepScheduler.from_pretrained(model, subfolder="scheduler"), |
|
"dpms_ms": DPMSolverMultistepScheduler.from_pretrained(model, subfolder="scheduler"), |
|
"dpms_ss": DPMSolverSinglestepScheduler.from_pretrained(model, subfolder="scheduler"), |
|
"euler_anc": EulerAncestralDiscreteScheduler.from_pretrained(model, subfolder="scheduler"), |
|
"euler": EulerDiscreteScheduler.from_pretrained(model, subfolder="scheduler"), |
|
"heun": HeunDiscreteScheduler.from_pretrained(model, subfolder="scheduler"), |
|
"kdpm2": KDPM2DiscreteScheduler.from_pretrained(model, subfolder="scheduler"), |
|
"lms": LMSDiscreteScheduler.from_pretrained(model, subfolder="scheduler"), |
|
"pndm": PNDMScheduler.from_pretrained(model, subfolder="scheduler"), |
|
"unipc": UniPCMultistepScheduler.from_pretrained(model, subfolder="scheduler") |
|
} |
|
if runSettings['task']=="img2img": |
|
init_image = Image.open(infile).convert("RGB") |
|
if args.cpu_textenc: |
|
cputextenc=OnnxRuntimeModel.from_pretrained(model+"/text_encoder") |
|
pipe = OnnxStableDiffusionImg2ImgPipeline.from_pretrained( |
|
model, |
|
provider="DmlExecutionProvider", |
|
revision="onnx", |
|
scheduler=sched['pndm'], |
|
text_encoder=cputextenc, |
|
safety_checker=None, |
|
feature_extractor=None |
|
) |
|
else: |
|
pipe = OnnxStableDiffusionImg2ImgPipeline.from_pretrained( |
|
model, |
|
provider="DmlExecutionProvider", |
|
revision="onnx", |
|
scheduler=sched['pndm'], |
|
safety_checker=None, |
|
feature_extractor=None |
|
) |
|
elif runSettings['task']=="controlnet": |
|
init_image = Image.open(infile).convert("RGB") |
|
if args.cpu_textenc: |
|
cputextenc=OnnxRuntimeModel.from_pretrained(model+"/text_encoder") |
|
pipe = OnnxStableDiffusionControlNetPipeline.from_pretrained( |
|
model, |
|
provider="DmlExecutionProvider", |
|
revision="onnx", |
|
scheduler=sched['pndm'], |
|
text_encoder=cputextenc, |
|
safety_checker=None, |
|
feature_extractor=None |
|
) |
|
else: |
|
pipe = OnnxStableDiffusionControlNetPipeline.from_pretrained( |
|
model, |
|
provider="DmlExecutionProvider", |
|
revision="onnx", |
|
scheduler=sched['pndm'], |
|
safety_checker=None, |
|
feature_extractor=None |
|
) |
|
else: |
|
if args.cpu_textenc: |
|
cputextenc=OnnxRuntimeModel.from_pretrained(model+"/text_encoder") |
|
pipe = OnnxStableDiffusionPipeline.from_pretrained( |
|
model, |
|
provider="DmlExecutionProvider", |
|
revision="onnx", |
|
scheduler=sched['pndm'], |
|
text_encoder=cputextenc, |
|
safety_checker=None, |
|
feature_extractor=None |
|
) |
|
else: |
|
pipe = OnnxStableDiffusionPipeline.from_pretrained( |
|
model, |
|
provider="DmlExecutionProvider", |
|
revision="onnx", |
|
scheduler=sched['pndm'], |
|
safety_checker=None, |
|
feature_extractor=None |
|
) |
|
if runSettings['textenc'] == "lpw": |
|
pipe._encode_prompt = functools.partial(lpw_pipe._encode_prompt, pipe) |
|
generator = numpy.random |
|
|
|
if len(runSettings['schedulerlist'])==0: |
|
schedulerlist=[runSettings['scheduler']] |
|
else: |
|
schedulerlist=runSettings['schedulerlist'] |
|
|
|
if len(runSettings['seedlist'])==0: |
|
if runSettings['seed']>runSettings['seedend']: |
|
runSettings['seedend']=runSettings['seed'] |
|
seedlist=range(runSettings['seed'],runSettings['seedend']+1) |
|
else: |
|
seedlist=runSettings['seedlist'] |
|
|
|
if len(runSettings['reslist'])==0: |
|
restuples=[(runSettings['width'],runSettings['height'])] |
|
else: |
|
restuples=[] |
|
for resstr in runSettings['reslist']: |
|
restuples.append(tuple(map(int, resstr.split("x")))) |
|
|
|
if len(runSettings['stepslist'])==0: |
|
stepslist=[runSettings['steps']] |
|
else: |
|
stepslist=runSettings['stepslist'] |
|
|
|
if len(runSettings['scalelist'])==0: |
|
scalelist=[runSettings['scale']] |
|
else: |
|
scalelist=runSettings['scalelist'] |
|
|
|
if len(runSettings['promptlist'])==0: |
|
promptlist=[runSettings['prompt']] |
|
else: |
|
promptlist=runSettings['promptlist'] |
|
|
|
if len(runSettings['strengthlist'])==0: |
|
strengthlist=[runSettings['strength']] |
|
else: |
|
strengthlist=runSettings['strengthlist'] |
|
imgnr=len(schedulerlist)*len(promptlist)*len(seedlist)*len(restuples)*len(stepslist)*len(scalelist)*len(strengthlist) |
|
imgdone=0 |
|
for scheduler in schedulerlist: |
|
if not sched[scheduler]: |
|
scheduler="pndm" |
|
pipe.scheduler=sched[scheduler] |
|
promptnum=0 |
|
for prompt in promptlist: |
|
for seed in seedlist: |
|
for res in restuples: |
|
for steps in stepslist: |
|
for scale in scalelist: |
|
for strength in strengthlist: |
|
if runSettings['task']=="img2img": |
|
filename=( |
|
f"{proj}/result-p{promptnum}-seed{seed}-{res[0]}x{res[1]}-"+ |
|
f"-steps-{steps}-{scheduler}-scale-"+str(scale).replace(".","_")+ |
|
"-strength-"+str(strength).replace(".","_")+".png" |
|
) |
|
elif runSettings['task']=="controlnet": |
|
filename=( |
|
f"{proj}/result-p{promptnum}-seed{seed}-{res[0]}x{res[1]}-"+ |
|
f"-steps-{steps}-{scheduler}-scale-"+str(scale).replace(".","_")+ |
|
"-strength-"+str(strength).replace(".","_")+".png" |
|
) |
|
else: |
|
filename=( |
|
f"{proj}/result-p{promptnum}-seed{seed}-{res[0]}x{res[1]}-"+ |
|
f"-steps-{steps}-{scheduler}-scale-"+str(scale).replace(".","_")+".png" |
|
) |
|
if not os.path.isfile(filename): |
|
generator.seed(seed) |
|
if runSettings['task']=="img2img": |
|
image = pipe( |
|
image=init_image, |
|
strength=strength, |
|
prompt=prompt, |
|
negative_prompt=runSettings['negative_prompt'], |
|
num_inference_steps=steps, |
|
guidance_scale=scale, |
|
generator=generator).images[0] |
|
elif runSettings['task']=="controlnet": |
|
image = pipe( |
|
image=init_image, |
|
controlnet_conditioning_scale=strength, |
|
prompt=prompt, |
|
negative_prompt=runSettings['negative_prompt'], |
|
num_inference_steps=steps, |
|
guidance_scale=scale, |
|
generator=generator).images[0] |
|
else: |
|
image = pipe( |
|
prompt=prompt, |
|
negative_prompt=runSettings['negative_prompt'], |
|
width=res[0], |
|
height=res[1], |
|
num_inference_steps=steps, |
|
guidance_scale=scale, |
|
generator = generator).images[0] |
|
metadata = PngImagePlugin.PngInfo() |
|
metadata.add_text("Generator","Stable Diffusion ONNX https://github.com/Amblyopius/Stable-Diffusion-ONNX-FP16") |
|
metadata.add_text("SD Model (local name)",model) |
|
metadata.add_text("SD Prompt",prompt) |
|
metadata.add_text("SD Negative Prompt",runSettings['negative_prompt']) |
|
metadata.add_text("SD Scheduler",scheduler) |
|
metadata.add_text("SD Steps",str(steps)) |
|
metadata.add_text("SD Guidance Scale",str(scale)) |
|
image.save(filename, pnginfo = metadata) |
|
else: |
|
print("Skipping existing image!") |
|
imgdone+=1 |
|
print(f"Finished {imgdone}/{imgnr}") |
|
promptnum+=1 |
|
del pipe |
|
gc.collect() |
|
else: |
|
print("Minimum requirements not met! Skipping") |
|
else: |
|
print("Settings not found! Skipping") |
|
else: |
|
print("Path not found! Skipping") |
|
|