From 08151c1ee9c88d5c6c32a235689db3735563f08b Mon Sep 17 00:00:00 2001 From: AIrjen Date: Tue, 20 Feb 2024 10:27:01 +0100 Subject: [PATCH] Support for Stable Cascade --- OneButtonPromptNodes.py | 19 +++++++++++------- build_dynamic_prompt.py | 40 ++++++++++++++++++++++++++++++-------- negativeprompttester.py | 6 +++--- prompttester.py | 7 ++++--- scripts/onebuttonprompt.py | 24 ++++++++++++++++------- 5 files changed, 68 insertions(+), 28 deletions(-) diff --git a/OneButtonPromptNodes.py b/OneButtonPromptNodes.py index 934f78a..b94a96c 100644 --- a/OneButtonPromptNodes.py +++ b/OneButtonPromptNodes.py @@ -23,6 +23,7 @@ subjects =["all", "object", "animal", "humanoid", "landscape", "concept"] genders = ["all", "male", "female"] emojis = [False, True] +models = ["SD1.5", "SDXL", "Stable Cascade"] subjects =["all"] subjectsubtypesobject = ["all"] subjectsubtypeshumanoid = ["all"] @@ -229,6 +230,7 @@ class OneButtonPrompt: "humanoids_gender": (genders, {"default": "all"}), "subject_subtypes_concepts": (subjectsubtypesconcept, {"default": "all"}), "emojis":(emojis, {"default": False}), + "base_model":(models, {"default": "SD1.5"}), "seed": ("INT", {"default": 0, "min": 0, "max": 0xFFFFFFFFFFFFFFFF}), }, @@ -243,8 +245,8 @@ class OneButtonPrompt: CATEGORY = "OneButtonPrompt" - def Comfy_OBP(self, insanitylevel, custom_subject, seed, artist, imagetype, subject, imagemodechance, humanoids_gender, subject_subtype_objects, subject_subtypes_humanoids, subject_subtypes_concepts, emojis, custom_outfit): - generatedpromptlist = build_dynamic_prompt(insanitylevel,subject,artist,imagetype,False,"","","",1,"",custom_subject,True,"",imagemodechance, humanoids_gender, subject_subtype_objects, subject_subtypes_humanoids, subject_subtypes_concepts, False, emojis, seed, custom_outfit, True) + def Comfy_OBP(self, insanitylevel, custom_subject, seed, artist, imagetype, subject, imagemodechance, humanoids_gender, subject_subtype_objects, subject_subtypes_humanoids, subject_subtypes_concepts, emojis, custom_outfit, base_model): + generatedpromptlist = build_dynamic_prompt(insanitylevel,subject,artist,imagetype,False,"","","",1,"",custom_subject,True,"",imagemodechance, humanoids_gender, subject_subtype_objects, subject_subtypes_humanoids, subject_subtypes_concepts, False, emojis, seed, custom_outfit, True, base_model) #print(generatedprompt) generatedprompt = generatedpromptlist[0] prompt_g = generatedpromptlist[1] @@ -451,7 +453,8 @@ class OneButtonPreset: "required": { "OneButtonPreset": (allpresets, {"default": "Standard"}), }, - "optional": { + "optional": { + "base_model":(models, {"default": "SD1.5"}), "seed": ("INT", {"default": 0, "min": 0, "max": 0xFFFFFFFFFFFFFFFF}), }, } @@ -466,7 +469,7 @@ class OneButtonPreset: CATEGORY = "OneButtonPrompt" - def Comfy_OBP_OneButtonPreset(self, OneButtonPreset, seed): + def Comfy_OBP_OneButtonPreset(self, OneButtonPreset, seed, base_model): # load the stuff selected_opb_preset = OBPresets.get_obp_preset(OneButtonPreset) @@ -505,7 +508,8 @@ class OneButtonPreset: antivalues=antistring, advancedprompting=False, hardturnoffemojis=True, - seed=seed + seed=seed, + base_model=base_model, ) @@ -541,6 +545,7 @@ class AutoNegativePrompt: "max": 10, #Maximum value "step": 1 #Slider's step }), + "base_model":(models, {"default": "SD1.5"}), "seed": ("INT", {"default": 0, "min": 0, "max": 0xFFFFFFFFFFFFFFFF}), }, @@ -555,8 +560,8 @@ class AutoNegativePrompt: CATEGORY = "OneButtonPrompt" - def Comfy_OBP_AutoNegativePrompt(self, postive_prompt, insanitylevel, enhancenegative,base_negative, seed): - generatedprompt = build_dynamic_negative(postive_prompt, insanitylevel, enhancenegative, base_negative) + def Comfy_OBP_AutoNegativePrompt(self, postive_prompt, insanitylevel, enhancenegative,base_negative, seed, base_model): + generatedprompt = build_dynamic_negative(postive_prompt, insanitylevel, enhancenegative, base_negative, base_model=base_model) print("Generated negative prompt: " + generatedprompt) diff --git a/build_dynamic_prompt.py b/build_dynamic_prompt.py index 3d13d47..beddbb1 100644 --- a/build_dynamic_prompt.py +++ b/build_dynamic_prompt.py @@ -10,7 +10,10 @@ from random_functions import * # insanity level controls randomness of propmt 0-10 # forcesubject van be used to force a certain type of subject # Set artistmode to none, to exclude artists -def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all", imagetype = "all", onlyartists = False, antivalues = "", prefixprompt = "", suffixprompt ="",promptcompounderlevel ="1", seperator = "comma", givensubject="",smartsubject = True,giventypeofimage="", imagemodechance = 20, gender = "all", subtypeobject="all", subtypehumanoid="all", subtypeconcept="all", advancedprompting=True, hardturnoffemojis=False, seed=-1, overrideoutfit="", prompt_g_and_l = False): +def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all", imagetype = "all", onlyartists = False, antivalues = "", prefixprompt = "", suffixprompt ="",promptcompounderlevel ="1", seperator = "comma", givensubject="",smartsubject = True,giventypeofimage="", imagemodechance = 20, gender = "all", subtypeobject="all", subtypehumanoid="all", subtypeconcept="all", advancedprompting=True, hardturnoffemojis=False, seed=-1, overrideoutfit="", prompt_g_and_l = False, base_model = "SD1.5"): + + remove_weights = False + # set seed # For use in ComfyUI (might bring to Automatic1111 as well) @@ -45,6 +48,16 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all # clean up antivalue list: antilist = [s.strip().lower() for s in antilist] + # Base model options, used to change things in prompt generation. Might be able to extend to different forms like animatediff as well? + base_model_options = ["SD1.5", "SDXL", "Stable Cascade"] + if base_model not in base_model_options: + base_model = "SD1.5" # Just in case there is no option here. + # "SD1.5" -- Standard, future: More original style prompting + # "SDXL" -- Standard (for now), future: More natural language + # "Stable Cascade" -- Remove weights + if base_model == "Stable Cascade": + remove_weights = True + # Some tricks for gender to make sure we can choose Him/Her/It etc on the right time. if(gender=="all"): genderchoicelist = ["male", "female"] @@ -1456,7 +1469,7 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all completeprompt += " [" while step < end: - if(normal_dist(insanitylevel)): + if(normal_dist(insanitylevel) and remove_weights == False): isweighted = 1 if isweighted == 1: @@ -1546,7 +1559,7 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all if(thetokinatormode == True): tokinatorsubtype = ["personification", "human form", "object", "landscape", "OR(creature;beast;animal;myth;concept;world;planet)", "building", "location", "shape", "being", "-token-"] if(chance_roll(insanitylevel,"normal")): - if(chance_roll(insanitylevel,"normal")): + if(chance_roll(insanitylevel,"normal") and remove_weights == False): completeprompt += "(OR(;-imagetypequality-;uncommon) OR(-imagetype-;-othertype-;rare):1.3) " else: completeprompt += "OR(;-imagetypequality-;uncommon) OR(-imagetype-;-othertype-;rare) " @@ -2274,7 +2287,7 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all completeprompt += " [" while step < end: - if(normal_dist(insanitylevel)): + if(normal_dist(insanitylevel) and remove_weights == False): isweighted = 1 if isweighted == 1: @@ -2600,7 +2613,7 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all completeprompt += " [" while step < end: - if(normal_dist(insanitylevel)): + if(normal_dist(insanitylevel) and remove_weights == False): isweighted = 1 if isweighted == 1: @@ -2984,7 +2997,7 @@ def build_dynamic_prompt(insanitylevel = 5, forcesubject = "all", artists = "all matches = re.findall(pattern, givensubject) - if(len(completeprompt) > 325 and matches == []): + if(len(completeprompt) > 325 and matches == [] and remove_weights == False): if(len(completeprompt) < 375): strenght = "1.1" elif(len(completeprompt) < 450): @@ -3863,12 +3876,23 @@ def replacewildcard(completeprompt, insanitylevel, wildcard,listname, activatehy return completeprompt -def build_dynamic_negative(positive_prompt = "", insanitylevel = 0, enhance = False, existing_negative_prompt = ""): +def build_dynamic_negative(positive_prompt = "", insanitylevel = 0, enhance = False, existing_negative_prompt = "", base_model="SD1.5"): negative_primer = [] negative_result = [] all_negative_words_list = [] + remove_weights = False + + # Base model options, used to change things in prompt generation. Might be able to extend to different forms like animatediff as well? + base_model_options = ["SD1.5", "SDXL", "Stable Cascade"] + if base_model not in base_model_options: + base_model = "SD1.5" # Just in case there is no option here. + # "SD1.5" -- Standard, future: More original style prompting + # "SDXL" -- Standard (for now), future: More natural language + # "Stable Cascade" -- Remove weights + if base_model == "Stable Cascade": + remove_weights = True # negavite_primer, all words that should trigger a negative result # the negative words to put in the negative prompt @@ -3937,7 +3961,7 @@ def build_dynamic_negative(positive_prompt = "", insanitylevel = 0, enhance = Fa # Convert the list to unique values or (word:count) format unique_words = [] for word, count in word_count.items(): - if(count > 2): + if(count > 2 and remove_weights == False): #counttotal = int(count/2) counttotal = count if(counttotal > 3): diff --git a/negativeprompttester.py b/negativeprompttester.py index 95e93ee..58866e8 100644 --- a/negativeprompttester.py +++ b/negativeprompttester.py @@ -10,7 +10,7 @@ from build_dynamic_prompt import * -def generateprompts(amount = 1,positive_prompt = "",insanitylevel="0",enhance=False,existing_negative_prompt=""): +def generateprompts(amount = 1,positive_prompt = "",insanitylevel="0",enhance=False,existing_negative_prompt="", base_model= "SD1.5"): loops = int(amount) # amount of images to generate steps = 0 @@ -19,7 +19,7 @@ def generateprompts(amount = 1,positive_prompt = "",insanitylevel="0",enhance=Fa # build prompt if positive_prompt == "": positive_prompt = build_dynamic_prompt() - result = build_dynamic_negative(positive_prompt=positive_prompt, insanitylevel=insanitylevel,enhance=enhance, existing_negative_prompt=existing_negative_prompt) + result = build_dynamic_negative(positive_prompt=positive_prompt, insanitylevel=insanitylevel,enhance=enhance, existing_negative_prompt=existing_negative_prompt, base_model=base_model) print("negative prompt: " + result) print("") print("loop " + str(steps)) @@ -32,4 +32,4 @@ def generateprompts(amount = 1,positive_prompt = "",insanitylevel="0",enhance=Fa print("") print("All done!") -generateprompts(1,"art by van gogh, a celestial being",0,False,"") \ No newline at end of file +generateprompts(1,"photo, photograph, realism",0,False,"", base_model="Stable Cascade") \ No newline at end of file diff --git a/prompttester.py b/prompttester.py index 2b75d73..e5e2b22 100644 --- a/prompttester.py +++ b/prompttester.py @@ -10,7 +10,7 @@ from build_dynamic_prompt import * -def generateprompts(amount = 1,insanitylevel="5",subject="all", artist="all", imagetype="all",onlyartists=False, workprompt="", antistring="",prefixprompt="", suffixprompt="", negativeprompt="",promptcompounderlevel = "1", seperator="comma",givensubject="",smartsubject=True,giventypeofimage="",imagemodechance=20, gender = "all", subtypeobject = "all", subtypehumanoid = "all", subtypeconcept = "all", advancedprompting = True, hardturnoffemojis=False, seed=0, overrideoutfit="", prompt_g_and_l = False): +def generateprompts(amount = 1,insanitylevel="5",subject="all", artist="all", imagetype="all",onlyartists=False, workprompt="", antistring="",prefixprompt="", suffixprompt="", negativeprompt="",promptcompounderlevel = "1", seperator="comma",givensubject="",smartsubject=True,giventypeofimage="",imagemodechance=20, gender = "all", subtypeobject = "all", subtypehumanoid = "all", subtypeconcept = "all", advancedprompting = True, hardturnoffemojis=False, seed=0, overrideoutfit="", prompt_g_and_l = False, base_model = "SD1.5"): loops = int(amount) # amount of images to generate steps = 0 @@ -18,7 +18,7 @@ def generateprompts(amount = 1,insanitylevel="5",subject="all", artist="all", im while steps < loops: # build prompt if(prompt_g_and_l == True): - resultlist = build_dynamic_prompt(insanitylevel,subject,artist,imagetype, onlyartists,antistring,prefixprompt,suffixprompt,promptcompounderlevel, seperator,givensubject,smartsubject,giventypeofimage,imagemodechance, gender, subtypeobject, subtypehumanoid, subtypeconcept, advancedprompting, hardturnoffemojis, seed, overrideoutfit, prompt_g_and_l) + resultlist = build_dynamic_prompt(insanitylevel,subject,artist,imagetype, onlyartists,antistring,prefixprompt,suffixprompt,promptcompounderlevel, seperator,givensubject,smartsubject,giventypeofimage,imagemodechance, gender, subtypeobject, subtypehumanoid, subtypeconcept, advancedprompting, hardturnoffemojis, seed, overrideoutfit, prompt_g_and_l, base_model) result = resultlist[0] print("prompt_g") print(resultlist[1]) @@ -26,7 +26,7 @@ def generateprompts(amount = 1,insanitylevel="5",subject="all", artist="all", im print(resultlist[2]) else: - result = build_dynamic_prompt(insanitylevel,subject,artist,imagetype, onlyartists,antistring,prefixprompt,suffixprompt,promptcompounderlevel, seperator,givensubject,smartsubject,giventypeofimage,imagemodechance, gender, subtypeobject, subtypehumanoid, subtypeconcept, advancedprompting, hardturnoffemojis, seed, overrideoutfit, prompt_g_and_l) + result = build_dynamic_prompt(insanitylevel,subject,artist,imagetype, onlyartists,antistring,prefixprompt,suffixprompt,promptcompounderlevel, seperator,givensubject,smartsubject,giventypeofimage,imagemodechance, gender, subtypeobject, subtypehumanoid, subtypeconcept, advancedprompting, hardturnoffemojis, seed, overrideoutfit, prompt_g_and_l, base_model) print("") print("loop " + str(steps)) print("") @@ -115,4 +115,5 @@ generateprompts(10,5 , 0 # seed , "" #outfit override , False #prompt_g_and_l + , "Stable Cascade" #base model ) \ No newline at end of file diff --git a/scripts/onebuttonprompt.py b/scripts/onebuttonprompt.py index cd750a0..b9ba46f 100644 --- a/scripts/onebuttonprompt.py +++ b/scripts/onebuttonprompt.py @@ -18,6 +18,7 @@ from csv_reader import * from one_button_presets import OneButtonPresets OBPresets = OneButtonPresets() +basemodelslist = ["SD1.5", "SDXL", "Stable Cascade"] #subjects = ["all","object","animal","humanoid", "landscape", "concept"] subjects =["all"] subjectsubtypesobject = ["all"] @@ -233,12 +234,12 @@ class Script(scripts.Script): def ui(self, is_img2img): - def gen_prompt(insanitylevel, subject, artist, imagetype, antistring, prefixprompt, suffixprompt, promptcompounderlevel, seperator,givensubject,smartsubject,giventypeofimage, imagemodechance,chosengender, chosensubjectsubtypeobject, chosensubjectsubtypehumanoid, chosensubjectsubtypeconcept,givenoutfit): + def gen_prompt(insanitylevel, subject, artist, imagetype, antistring, prefixprompt, suffixprompt, promptcompounderlevel, seperator,givensubject,smartsubject,giventypeofimage, imagemodechance,chosengender, chosensubjectsubtypeobject, chosensubjectsubtypehumanoid, chosensubjectsubtypeconcept,givenoutfit, base_model): promptlist = [] for i in range(5): - promptlist.append(build_dynamic_prompt(insanitylevel,subject,artist, imagetype, False, antistring,prefixprompt,suffixprompt,promptcompounderlevel,seperator,givensubject,smartsubject, giventypeofimage, imagemodechance,chosengender, chosensubjectsubtypeobject, chosensubjectsubtypehumanoid, chosensubjectsubtypeconcept,True,False,-1,givenoutfit)) + promptlist.append(build_dynamic_prompt(insanitylevel,subject,artist, imagetype, False, antistring,prefixprompt,suffixprompt,promptcompounderlevel,seperator,givensubject,smartsubject, giventypeofimage, imagemodechance,chosengender, chosensubjectsubtypeobject, chosensubjectsubtypehumanoid, chosensubjectsubtypeconcept,True,False,-1,givenoutfit,False,base_model)) return promptlist @@ -627,6 +628,15 @@ class Script(scripts.Script): with gr.Column(variant="compact"): prompt5toworkflow = gr.Button("⬆️🛠️💬") with gr.Tab("Advanced"): + with gr.Row(variant="compact"): + gr.Markdown(""" + + Base model will try and generate prompts fitting the selected model. + + """ + ) + base_model = gr.Dropdown( + basemodelslist, label=" Base model", value="SD1.5") with gr.Row(variant="compact"): with gr.Column(variant="compact"): promptcompounderlevel = gr.Dropdown( @@ -1201,12 +1211,12 @@ class Script(scripts.Script): - return [insanitylevel,subject, artist, imagetype, prefixprompt,suffixprompt,negativeprompt, promptcompounderlevel, ANDtoggle, silentmode, workprompt, antistring, seperator, givensubject, smartsubject, giventypeofimage, imagemodechance, chosengender, chosensubjectsubtypeobject, chosensubjectsubtypehumanoid, chosensubjectsubtypeconcept, promptvariantinsanitylevel, givenoutfit, autonegativeprompt, autonegativepromptstrength, autonegativepromptenhance] + return [insanitylevel,subject, artist, imagetype, prefixprompt,suffixprompt,negativeprompt, promptcompounderlevel, ANDtoggle, silentmode, workprompt, antistring, seperator, givensubject, smartsubject, giventypeofimage, imagemodechance, chosengender, chosensubjectsubtypeobject, chosensubjectsubtypehumanoid, chosensubjectsubtypeconcept, promptvariantinsanitylevel, givenoutfit, autonegativeprompt, autonegativepromptstrength, autonegativepromptenhance, base_model] - def run(self, p, insanitylevel, subject, artist, imagetype, prefixprompt,suffixprompt,negativeprompt, promptcompounderlevel, ANDtoggle, silentmode, workprompt, antistring,seperator, givensubject, smartsubject, giventypeofimage, imagemodechance, chosengender, chosensubjectsubtypeobject, chosensubjectsubtypehumanoid, chosensubjectsubtypeconcept, promptvariantinsanitylevel, givenoutfit, autonegativeprompt, autonegativepromptstrength, autonegativepromptenhance): + def run(self, p, insanitylevel, subject, artist, imagetype, prefixprompt,suffixprompt,negativeprompt, promptcompounderlevel, ANDtoggle, silentmode, workprompt, antistring,seperator, givensubject, smartsubject, giventypeofimage, imagemodechance, chosengender, chosensubjectsubtypeobject, chosensubjectsubtypehumanoid, chosensubjectsubtypeconcept, promptvariantinsanitylevel, givenoutfit, autonegativeprompt, autonegativepromptstrength, autonegativepromptenhance, base_model): images = [] infotexts = [] @@ -1253,7 +1263,7 @@ class Script(scripts.Script): if(ANDtoggle == "automatic"): if(artist != "none"): - preppedprompt += build_dynamic_prompt(insanitylevel,subject,artist, imagetype, True, antistring) + preppedprompt += build_dynamic_prompt(insanitylevel,subject,artist, imagetype, True, antistring, base_model=base_model) if(subject == "humanoid"): preppedprompt += ", " + promptcompounderlevel + " people" if(subject == "landscape"): @@ -1280,7 +1290,7 @@ class Script(scripts.Script): #Here is where we build a "normal" prompt - preppedprompt += build_dynamic_prompt(insanitylevel,subject,artist, imagetype, False, antistring, prefixprompt, suffixprompt,promptcompounderlevel, seperator,givensubject,smartsubject,giventypeofimage,imagemodechance,chosengender, chosensubjectsubtypeobject, chosensubjectsubtypehumanoid, chosensubjectsubtypeconcept,True,False,-1,givenoutfit) + preppedprompt += build_dynamic_prompt(insanitylevel,subject,artist, imagetype, False, antistring, prefixprompt, suffixprompt,promptcompounderlevel, seperator,givensubject,smartsubject,giventypeofimage,imagemodechance,chosengender, chosensubjectsubtypeobject, chosensubjectsubtypehumanoid, chosensubjectsubtypeconcept,True,False,-1,givenoutfit, False, base_model) # set the artist mode back when done (for automatic mode) artist = artistcopy @@ -1301,7 +1311,7 @@ class Script(scripts.Script): print(p.prompt) if(autonegativeprompt): - p.negative_prompt = build_dynamic_negative(positive_prompt=p.prompt, insanitylevel=autonegativepromptstrength,enhance=autonegativepromptenhance, existing_negative_prompt=p.negative_prompt) + p.negative_prompt = build_dynamic_negative(positive_prompt=p.prompt, insanitylevel=autonegativepromptstrength,enhance=autonegativepromptenhance, existing_negative_prompt=p.negative_prompt, base_model=base_model) promptlist = []