mirror of
https://github.com/mudler/LocalAI.git
synced 2026-10-28 09:08:54 -04:00
fix(diffusers): keep negative_prompt unless negative embeds are set
The sd_embed branch dropped negative_prompt for every pipeline, which discarded the user's negative prompt for Flux, where no negative embeds are produced. Only drop it when negative_prompt_embeds is present, and move the check to a helper that has unit tests. Assisted-by: Claude Code:claude-sonnet-5-5 Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
This commit is contained in:
3 files changed
+38
-5
No files matched your search
@@ -36,7 +36,7 @@ from diffusers_dynamic_loader import (
|
||||
get_available_pipelines,
|
||||
load_diffusers_pipeline,
|
||||
)
|
||||
from load_options import single_file_load_kwargs
|
||||
from load_options import drop_negative_prompt_if_embedded, single_file_load_kwargs
|
||||
|
||||
# Import specific items still needed for special cases and safety checker
|
||||
from diffusers import DiffusionPipeline, ControlNetModel
|
||||
@@ -882,9 +882,9 @@ class BackendServicer(backend_pb2_grpc.BackendServicer):
|
||||
prompt = prompt,
|
||||
)
|
||||
|
||||
# remove negative_prompt that may have been added earlier from options to avoid conflict
|
||||
# errors from passing both negative_prompt and negative_prompt_embeds
|
||||
kwargs.pop('negative_prompt', None)
|
||||
# negative_prompt conflicts with negative_prompt_embeds; pipelines that
|
||||
# got no negative embeds (e.g. Flux) keep the user's negative prompt
|
||||
drop_negative_prompt_if_embedded(kwargs)
|
||||
|
||||
image = self.pipe(
|
||||
guidance_scale=self.cfg_scale,
|
||||
|
||||
@@ -5,3 +5,14 @@ def single_file_load_kwargs(original_config_file: str, from_single_file: bool) -
|
||||
if from_single_file and original_config_file:
|
||||
return {"original_config_file": original_config_file}
|
||||
return {}
|
||||
|
||||
|
||||
def drop_negative_prompt_if_embedded(kwargs: dict) -> dict:
|
||||
"""Remove negative_prompt from pipeline kwargs when negative_prompt_embeds is set.
|
||||
|
||||
Diffusers rejects both being passed together. Pipelines without negative
|
||||
embeddings keep the user's negative prompt.
|
||||
"""
|
||||
if "negative_prompt_embeds" in kwargs:
|
||||
kwargs.pop("negative_prompt", None)
|
||||
return kwargs
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
import unittest
|
||||
|
||||
from backend.python.diffusers.load_options import single_file_load_kwargs
|
||||
from backend.python.diffusers.load_options import (
|
||||
drop_negative_prompt_if_embedded,
|
||||
single_file_load_kwargs,
|
||||
)
|
||||
|
||||
|
||||
class SingleFileLoadKwargsTest(unittest.TestCase):
|
||||
@@ -22,5 +25,24 @@ class SingleFileLoadKwargsTest(unittest.TestCase):
|
||||
self.assertEqual(single_file_load_kwargs("", True), {})
|
||||
|
||||
|
||||
class DropNegativePromptTest(unittest.TestCase):
|
||||
def test_drops_negative_prompt_when_embeds_present(self):
|
||||
kwargs = {"negative_prompt": "blurry", "negative_prompt_embeds": object()}
|
||||
drop_negative_prompt_if_embedded(kwargs)
|
||||
self.assertNotIn("negative_prompt", kwargs)
|
||||
self.assertIn("negative_prompt_embeds", kwargs)
|
||||
|
||||
def test_keeps_negative_prompt_without_embeds(self):
|
||||
kwargs = {"negative_prompt": "blurry", "prompt_embeds": object()}
|
||||
drop_negative_prompt_if_embedded(kwargs)
|
||||
self.assertEqual(kwargs["negative_prompt"], "blurry")
|
||||
|
||||
def test_no_negative_prompt_is_fine(self):
|
||||
self.assertEqual(
|
||||
drop_negative_prompt_if_embedded({"negative_prompt_embeds": 1}),
|
||||
{"negative_prompt_embeds": 1},
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user