diff --git a/CHANGELOG b/CHANGELOG index 1f8417d..7bcc3e0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -16,3 +16,4 @@ 0.9.2 Added additional artists and refactored code. 0.10.0 Added magic prompts 0.11.0 Migrated to an extension +0.12.0 Added a slider to enable combinatorial generation in batches, in other words, run the same set of prompts with different seeds diff --git a/README.md b/README.md index 5bddabd..68b1058 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,8 @@ Combinatorial generation can be useful if you want to create an image for every Combinations are not yet supported, i.e. `{2$$a|b|c}` will treat `2$$a` as one of the options instead of selecting two of a, b and c. +The combinatorial batches slider lets you repeat the same set of prompts a number of times with different seeds. The default number of batches is 1. + ## Magic Prompt Using [Gustavosta](https://huggingface.co/Gustavosta/MagicPrompt-Stable-Diffusion)'s MagicPrompt model, automatically generate neww prompts from the input. Trained on 80,000 prompts from [Lexica.art](lexica.art), it can help give you interesting new prompts on a given subject. Here are some automatically generated variations for "dogs playing football": diff --git a/prompts/generators/__init__.py b/prompts/generators/__init__.py index f8bfafd..36e1df5 100644 --- a/prompts/generators/__init__.py +++ b/prompts/generators/__init__.py @@ -8,3 +8,4 @@ re_combinations = re.compile(r"\{([^{}]*)}") from .randomprompt import RandomPromptGenerator from .combinatorial import CombinatorialPromptGenerator from .magicprompt import MagicPromptGenerator +from .batched_combinatorial import BatchedCombinatorialPromptGenerator diff --git a/prompts/generators/batched_combinatorial.py b/prompts/generators/batched_combinatorial.py new file mode 100644 index 0000000..fbc319e --- /dev/null +++ b/prompts/generators/batched_combinatorial.py @@ -0,0 +1,21 @@ +from itertools import chain +import logging + +from prompts.wildcardmanager import WildcardManager +from prompts import constants +from . import PromptGenerator, re_combinations, re_wildcard + +logger = logging.getLogger(__name__) + + +class BatchedCombinatorialPromptGenerator(PromptGenerator): + def __init__(self, generator: PromptGenerator, batches=1): + self._generator = generator + self._batches = batches + + def generate(self, max_prompts=constants.MAX_IMAGES) -> list[str]: + images = [] + + for _ in range(self._batches): + images.extend(self._generator.generate(max_prompts)) + return images diff --git a/scripts/dynamic_prompting.py b/scripts/dynamic_prompting.py index 0486527..74a0b96 100644 --- a/scripts/dynamic_prompting.py +++ b/scripts/dynamic_prompting.py @@ -11,16 +11,17 @@ from modules.shared import opts from prompts.wildcardmanager import WildcardManager from prompts.uicreation import UiCreation -from prompts.generators import RandomPromptGenerator, CombinatorialPromptGenerator, MagicPromptGenerator +from prompts.generators import RandomPromptGenerator, CombinatorialPromptGenerator, MagicPromptGenerator, BatchedCombinatorialPromptGenerator logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) -WILDCARD_DIR = getattr(opts, "wildcard_dir", base_dir / "wildcards") -VERSION = "0.11.0" - base_dir = Path(scripts.basedir()) +WILDCARD_DIR = getattr(opts, "wildcard_dir", base_dir / "wildcards") +VERSION = "0.12.0" + + wildcard_manager = WildcardManager(WILDCARD_DIR) class Script(scripts.Script): @@ -36,18 +37,22 @@ class Script(scripts.Script): html = Template(html).substitute(wildcard_html=wildcard_html, WILDCARD_DIR=WILDCARD_DIR) is_combinatorial = gr.Checkbox(label="Combinatorial generation", value=False, elem_id="is-combinatorial") + combinatorial_batches = gr.Slider(label="Combinatorial batches", min=1, max=10, step=1, value=1, elem_id="combinatorial-times") is_magic_prompt = gr.Checkbox(label="Magic prompt", value=False, elem_id="is-magicprompt") info = gr.HTML(html) - return [info, is_combinatorial, is_magic_prompt] + return [info, is_combinatorial, combinatorial_batches, is_magic_prompt] - def run(self, p, info, is_combinatorial, is_magic_prompt): + def run(self, p, info, is_combinatorial, combinatorial_batches, is_magic_prompt): fix_seed(p) original_prompt = p.prompt[0] if type(p.prompt) == list else p.prompt original_seed = p.seed + if combinatorial_batches < 1: + combinatorial_batches = 1 if is_combinatorial: prompt_generator = CombinatorialPromptGenerator(wildcard_manager, original_prompt) + prompt_generator = BatchedCombinatorialPromptGenerator(prompt_generator, combinatorial_batches) else: prompt_generator = RandomPromptGenerator(wildcard_manager, original_prompt, original_seed)