From 3f73ef84a0fd231a6dff1eccb68ef585ce48a4b7 Mon Sep 17 00:00:00 2001 From: AdiosF6F <62105+Adios@users.noreply.github.com> Date: Mon, 8 Dec 2025 21:05:54 +0800 Subject: [PATCH] fix(combinatorial): Fix inflated image counts and duplicate generation This commit fixes a critical bug in the combinatorial generation feature where the underlying library produced an inflated number of prompts and a malformed list structure. The issues addressed are: 1. **Count Inflation:** The prompt count was incorrectly calculated as `Combinations * Batches^2`, causing the generation of significantly more images than requested. 2. **Identical Duplicates:** The prompt list was structured as `[P1, P1, P2, P2]`. When combined with the extension's seeding logic (which generates seeds as `[S, S, S+1, S+1]`), this resulted in identical `(P1, S)` and `(P1, S)` pairs. This patch adds logic to intercept the generated prompt list, trim it to the correct length (`Combinations * Batches`), and reorder it to `[P1, P2, P1, P2]`. This ensures that every generated image is a unique combination of prompt and seed, and matches the expected output count. --- sd_dynamic_prompts/dynamic_prompting.py | 33 +++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/sd_dynamic_prompts/dynamic_prompting.py b/sd_dynamic_prompts/dynamic_prompting.py index f8367425..834d1853 100644 --- a/sd_dynamic_prompts/dynamic_prompting.py +++ b/sd_dynamic_prompts/dynamic_prompting.py @@ -491,6 +491,39 @@ def process( all_prompts = [str(e)] all_negative_prompts = [str(e)] + if is_combinatorial: + # The underlying library has two bugs: + # 1. It calculates prompts as (Combinations * Batches * Batches) + # 2. It structures the list as [P1,P1, P2,P2,...] instead of [P1,P2, P1,P2,...] + # The following logic deconstructs the buggy list to get a clean, unique set of base combinations. + + # Step 1: Correct for the C*B*B length bug to get a list of C*B prompts + if combinatorial_batches > 0 and len(all_prompts) > combinatorial_batches: + base_prompt_count = len(all_prompts) // combinatorial_batches + all_prompts = all_prompts[:base_prompt_count] + all_negative_prompts = repeat_iterable_to_length( + all_negative_prompts, + len(all_prompts), + ) + + # Step 2: Correct for the [P1,P1,P2,P2] structural bug by de-duplicating the list + if combinatorial_batches > 1: + # This is a trick to get every Nth element, where N is the number of batches. + # It reconstructs the unique list of combinations. + all_prompts = all_prompts[::combinatorial_batches] + all_negative_prompts = repeat_iterable_to_length( + all_negative_prompts, + len(all_prompts), + ) + + # Step 3: Now we have a clean list of base prompts (C). We apply OUR multipliers. + # First, apply the script's own "Combinatorial batches" multiplier + all_prompts = all_prompts * combinatorial_batches + all_negative_prompts = repeat_iterable_to_length( + all_negative_prompts, + len(all_prompts) + ) + updated_count = len(all_prompts) p.n_iter = math.ceil(updated_count / p.batch_size)