ljleb / sd-webui-neutral-prompt

Collision-free AND keywords for a1111 webui!
MIT License
187 stars 13 forks source link

broken? #55

Closed dm18 closed 7 months ago

dm18 commented 9 months ago

is this still compatible with automatic1111?

Asking, because when I try to use it, I throw the following error when I try to use AND_PERP, AND_SALT, AND_TOPK.

Traceback (most recent call last): File "C:\Users\T\stable-diffusion-webui\modules\call_queue.py", line 57, in f res = list(func(*args, **kwargs)) File "C:\Users\T\stable-diffusion-webui\modules\call_queue.py", line 36, in f res = func(*args, **kwargs) File "C:\Users\T\stable-diffusion-webui\modules\txt2img.py", line 55, in txt2img processed = processing.process_images(p) File "C:\Users\T\stable-diffusion-webui\modules\processing.py", line 732, in process_images res = process_images_inner(p) File "C:\Users\T\stable-diffusion-webui\modules\processing.py", line 856, in process_images_inner p.setup_conds() File "C:\Users\T\stable-diffusion-webui\modules\processing.py", line 1309, in setup_conds super().setup_conds() File "C:\Users\T\stable-diffusion-webui\modules\processing.py", line 470, in setup_conds self.c = self.get_conds_with_caching(prompt_parser.get_multicond_learned_conditioning, prompts, total_steps, [self.cached_c], self.extra_network_data) File "C:\Users\T\stable-diffusion-webui\modules\processing.py", line 455, in get_conds_with_caching cache[1] = function(shared.sd_model, required_prompts, steps, hires_steps, shared.opts.use_old_scheduling) File "C:\Users\T\stable-diffusion-webui\modules\prompt_parser.py", line 260, in get_multicond_learned_conditioning res_indexes, prompt_flat_list, prompt_indexes = get_multicond_prompt_list(prompts) File "C:\Users\T\stable-diffusion-webui\extensions\sd-webui-neutral-prompt\lib_neutral_prompt\prompt_parser_hijack.py", line 19, in get_multicond_prompt_list_hijack global_state.prompt_exprs = parse_prompts(prompts) File "C:\Users\T\stable-diffusion-webui\extensions\sd-webui-neutral-prompt\lib_neutral_prompt\prompt_parser_hijack.py", line 30, in parse_prompts expr = neutral_prompt_parser.parse_root(prompt) File "C:\Users\T\stable-diffusion-webui\extensions\sd-webui-neutral-prompt\lib_neutral_prompt\neutral_prompt_parser.py", line 63, in parse_root prompts = parse_prompts(tokens) File "C:\Users\T\stable-diffusion-webui\extensions\sd-webui-neutral-prompt\lib_neutral_prompt\neutral_prompt_parser.py", line 73, in parse_prompts prompts.append(parse_prompt(tokens, first=False)) File "C:\Users\T\stable-diffusion-webui\extensions\sd-webui-neutral-prompt\lib_neutral_prompt\neutral_prompt_parser.py", line 82, in parse_prompt assert tokens[0] in prompt_keywords AssertionError

ljleb commented 9 months ago

Is this 1.7.0-RC? I would appreciate if you could share the prompt you are using so I can reproduce/debug. I'll try to fix this tomorrow.

ljleb commented 9 months ago

Unfortunately I am not able to reproduce with a basic AND_PERP prompt. Make sure the extension is up to date.

ljleb commented 9 months ago

I found an error case that causes this to happen. Basically, this will happen when you start your prompt with square brackets but the entire prompt isn't enclosed in square brackets, i.e.:

AND_PERP [prompt] you thought it was the end

Square brackets have been overloaded with nested prompting, and for this reason it's a bit tricky to get them to work correctly:

a
AND_PERP [
    b
    AND_SALT
    c
]

Will add a test case and fix the parser. For now, a workaround is to enclose the entire prompt with square brackets:

AND_PERP [[prompt] you thought it was the end]
ljleb commented 9 months ago

Pushed a fix. I ran a couple of manual tests on top of the test suite. Let me know if it works or please share a problematic prompt so that I can add it as a test case.

wbclark commented 7 months ago

I believe this is still broken when the first prompt starts with square brackets, as the fix only applies when parse_prompt is called with first=False.

Ex. 1: [first] prompt AND_PERP second prompt

Ex. 2: [ first prompt AND_PERP second prompt ] AND_SALT third prompt (not sure yet if this works even if the parsing is fixed, need to do further testing on it)

I added some print debugging that shows the resulting hierarchy of LeafPrompt and CompositePrompt objects, I can provide some examples later showing exactly how the prompts are getting parsed.

ljleb commented 7 months ago

I can provide some examples later showing exactly how the prompts are getting parsed.

Thanks for the examples. Up to you if you want to share the hierarchy, but I can debug the examples you shared above.

In any case, I think this is a syntax conflict that needs to be more thoroughly analyzed. The problem is that the extension needs to use some kind of open-closed brackets to represent prompt nesting, however all simple bracket types have already been reserved for other purposes in the builtin webui syntax. I tried to be clever and use square brackets for this, but clearly it leads to ambiguity if the first character of the prompt is an open square bracket. Also the parser code is not really maintainable currently, I need to rewrite it.

Allowing custom prompt syntax in the extension settings is not a good solution IMO since it makes reproducing generations impractical on different installations with different configurations. We need a fixed syntax that isn't ambiguous even if it has to parse in polynomial time.

Let me lay down some test cases for later. Ideally, we want:

So TL;DR, I think we want [...] to mean "prompt grouping" only when there's an AND_* keyword inside. It's been a while I contributed to this repo, but IIUC the extra weight w2 in a AND_* [b :w1]:w2 may not be useful, regardless of the type of AND_* keyword used.

ljleb commented 7 months ago

Should be fixed now. I added a couple more test cases. Please let me know if you find another problematic prompt, it will be my pleasure to spend more time to make it robust.