Skip to content

Commit e66e8c1

Browse files
committed
Added support for adjusting text prompt strengths (useful in Revision mode)
1 parent f542eb4 commit e66e8c1

8 files changed

+61
-44
lines changed

modules/async_worker.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def handler(task):
6060
base_model_name, refiner_model_name, base_clip_skip, refiner_clip_skip, \
6161
l1, w1, l2, w2, l3, w3, l4, w4, l5, w5, save_metadata_json, save_metadata_image, \
6262
img2img_mode, img2img_start_step, img2img_denoise, \
63-
revision_mode, zero_out_positive, zero_out_negative, revision_strength_1, revision_strength_2, \
63+
revision_mode, positive_prompt_strength, negative_prompt_strength, revision_strength_1, revision_strength_2, \
6464
revision_strength_3, revision_strength_4, same_seed_for_all, output_format, \
6565
control_lora_canny, canny_edge_low, canny_edge_high, canny_start, canny_stop, canny_strength, canny_model, \
6666
control_lora_depth, depth_start, depth_stop, depth_strength, depth_model, prompt_expansion, \
@@ -127,11 +127,11 @@ def handler(task):
127127
if not prompt_expansion:
128128
outputs.append(['preview', (5, 'Encoding negative text ...', None)])
129129
n_txt = apply_style_negative(style, negative_prompt)
130-
n_cond = pipeline.process_prompt(n_txt, base_clip_skip, refiner_clip_skip, zero_out_negative)
130+
n_cond = pipeline.process_prompt(n_txt, base_clip_skip, refiner_clip_skip, negative_prompt_strength)
131131

132132
outputs.append(['preview', (9, 'Encoding positive text ...', None)])
133133
p_txt = apply_style_positive(style, prompt)
134-
p_cond = pipeline.process_prompt(p_txt, base_clip_skip, refiner_clip_skip, zero_out_positive, revision_mode, revision_strengths, clip_vision_outputs)
134+
p_cond = pipeline.process_prompt(p_txt, base_clip_skip, refiner_clip_skip, positive_prompt_strength, revision_mode, revision_strengths, clip_vision_outputs)
135135

136136
for i in range(image_number):
137137
current_seed = seed if same_seed_for_all else seed + i
@@ -162,12 +162,12 @@ def handler(task):
162162

163163
outputs.append(['preview', (9, 'Encoding negative text ...', None)])
164164
n_txt = apply_style_negative(style, negative_prompt)
165-
n_cond = pipeline.process_prompt(n_txt, base_clip_skip, refiner_clip_skip, zero_out_negative)
165+
n_cond = pipeline.process_prompt(n_txt, base_clip_skip, refiner_clip_skip, negative_prompt_strength)
166166

167167
for i, t in enumerate(tasks):
168168
outputs.append(['preview', (12, f'Encoding positive text #{i + 1} ...', None)])
169169
t['p_cond'] = pipeline.process_prompt(t['real_positive_prompt'], base_clip_skip, refiner_clip_skip,
170-
zero_out_positive, revision_mode, revision_strengths, clip_vision_outputs)
170+
positive_prompt_strength, revision_mode, revision_strengths, clip_vision_outputs)
171171
t['real_negative_prompt'] = n_txt
172172
t['n_cond'] = n_cond
173173

@@ -249,7 +249,7 @@ def callback(step, x0, x, total_steps, y):
249249
'base_model': base_model_name, 'refiner_model': refiner_model_name,
250250
'l1': l1, 'w1': w1, 'l2': l2, 'w2': w2, 'l3': l3, 'w3': w3,
251251
'l4': l4, 'w4': w4, 'l5': l5, 'w5': w5, 'img2img': img2img_mode, 'revision': revision_mode,
252-
'zero_out_positive': zero_out_positive, 'zero_out_negative': zero_out_negative,
252+
'positive_prompt_strength': positive_prompt_strength, 'negative_prompt_strength': negative_prompt_strength,
253253
'control_lora_canny': control_lora_canny, 'control_lora_depth': control_lora_depth,
254254
'prompt_expansion': prompt_expansion
255255
}
@@ -296,7 +296,7 @@ def callback(step, x0, x, total_steps, y):
296296
('Image-2-Image', (img2img_mode, start_step, denoise, input_image_filename) if img2img_mode else (img2img_mode)),
297297
('Revision', (revision_mode, revision_strength_1, revision_strength_2, revision_strength_3,
298298
revision_strength_4, revision_images_filenames) if revision_mode else (revision_mode)),
299-
('Zero Out Prompts', (zero_out_positive, zero_out_negative)),
299+
('Prompt Strengths', (positive_prompt_strength, negative_prompt_strength)),
300300
('Canny', (control_lora_canny, canny_edge_low, canny_edge_high, canny_start, canny_stop,
301301
canny_strength, canny_model, input_image_filename) if control_lora_canny else (control_lora_canny)),
302302
('Depth', (control_lora_depth, depth_start, depth_stop, depth_strength, depth_model, input_image_filename) if control_lora_depth else (control_lora_depth))

modules/core.py

+12-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from comfy.sd import load_checkpoint_guess_config
1111
from nodes import VAEDecode, EmptyLatentImage, CLIPTextEncode, VAEEncode, \
12-
ConditioningZeroOut, CLIPVisionEncode, unCLIPConditioning, ControlNetApplyAdvanced
12+
ConditioningZeroOut, ConditioningAverage, CLIPVisionEncode, unCLIPConditioning, ControlNetApplyAdvanced
1313
from comfy.sample import prepare_mask, broadcast_cond, get_additional_models, cleanup_additional_models
1414
from comfy_extras.nodes_post_processing import ImageScaleToTotalPixels
1515
from comfy_extras.nodes_canny import Canny
@@ -25,6 +25,7 @@
2525
opVAEEncode = VAEEncode()
2626
opImageScaleToTotalPixels = ImageScaleToTotalPixels()
2727
opConditioningZeroOut = ConditioningZeroOut()
28+
opConditioningAverage = ConditioningAverage()
2829
opCLIPVisionEncode = CLIPVisionEncode()
2930
opUnCLIPConditioning = unCLIPConditioning()
3031
opCanny = Canny()
@@ -102,6 +103,16 @@ def zero_out(conditioning):
102103
return opConditioningZeroOut.zero_out(conditioning=conditioning)[0]
103104

104105

106+
@torch.no_grad()
107+
def average(conditioning_to, conditioning_from, conditioning_to_strength):
108+
return opConditioningAverage.addWeighted(conditioning_to=conditioning_to, conditioning_from=conditioning_from, conditioning_to_strength=conditioning_to_strength)[0]
109+
110+
111+
@torch.no_grad()
112+
def set_conditioning_strength(conditioning, strength):
113+
return average(conditioning, zero_out(conditioning), strength)
114+
115+
105116
@torch.no_grad()
106117
def encode_clip_vision(clip_vision, image):
107118
return opCLIPVisionEncode.encode(clip_vision=clip_vision, image=image)[0]

modules/default_pipeline.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,11 @@ def expand_txt(*args, **kwargs):
166166
return expansion_model(*args, **kwargs)
167167

168168

169-
def process_prompt(text, base_clip_skip, refiner_clip_skip, zero_out=False, revision=False, revision_strengths=[], clip_vision_outputs=[]):
169+
def process_prompt(text, base_clip_skip, refiner_clip_skip, prompt_strength=1.0, revision=False, revision_strengths=[], clip_vision_outputs=[]):
170170
xl_base_patched.clip.clip_layer(base_clip_skip)
171171
base_cond = core.encode_prompt_condition(clip=xl_base_patched.clip, prompt=text)
172-
if zero_out:
173-
base_cond = core.zero_out(base_cond)
172+
if prompt_strength >= 0 and prompt_strength < 1.0:
173+
base_cond = core.set_conditioning_strength(base_cond, prompt_strength)
174174

175175
if revision:
176176
set_comfy_adm_encoding()
@@ -183,8 +183,8 @@ def process_prompt(text, base_clip_skip, refiner_clip_skip, zero_out=False, revi
183183
if xl_refiner is not None:
184184
xl_refiner.clip.clip_layer(refiner_clip_skip)
185185
refiner_cond = core.encode_prompt_condition(clip=xl_refiner.clip, prompt=text)
186-
if zero_out:
187-
refiner_cond = core.zero_out(refiner_cond)
186+
if prompt_strength >= 0 and prompt_strength < 1.0:
187+
refiner_cond = core.set_conditioning_strength(refiner_cond, prompt_strength)
188188
else:
189189
refiner_cond = None
190190
return base_cond, refiner_cond

modules/settings.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ def load_settings():
3939
settings['depth_model'] = modules.path.default_controlnet_depth_name
4040
settings['keep_input_names'] = False
4141
settings['revision_mode'] = False
42-
settings['zero_out_positive'] = False
43-
settings['zero_out_negative'] = False
42+
settings['positive_prompt_strength'] = 1.0
43+
settings['negative_prompt_strength'] = 1.0
4444
settings['revision_strength_1'] = 1.0
4545
settings['revision_strength_2'] = 1.0
4646
settings['revision_strength_3'] = 1.0

readme.md

+20-19
Original file line numberDiff line numberDiff line change
@@ -121,25 +121,26 @@ Below things are already inside the software, and **users do not need to do anyt
121121
2. Support for Control-LoRA: Canny Edge (guiding diffusion using edge detection on input, see [Canny Edge description from SAI](https://huggingface.co/stabilityai/control-lora#canny-edge)).
122122
3. Support for Control-LoRA: Depth (guiding diffusion using depth information from input, see [Depth description from SAI](https://huggingface.co/stabilityai/control-lora#midas-and-clipdrop-depth)).
123123
4. Support for Control-LoRA: Revision (prompting with images, see [Revision description from SAI](https://huggingface.co/stabilityai/control-lora#revision)).
124-
5. Support for embeddings (use "embedding:embedding_name" syntax, ComfyUI style).
125-
6. Customizable sampling parameters (sampler, scheduler, steps, base / refiner switch point, CFG, CLIP Skip).
126-
7. Displaying full metadata for generated images in the UI.
127-
8. Support for JPEG format.
128-
9. Ability to save full metadata for generated images (as JSON or embedded in image, disabled by default).
129-
10. Ability to load prompt information from JSON and image files (if saved with metadata).
130-
11. Ability to change default values of UI settings (loaded from settings.json file - use settings-example.json as a template).
131-
12. Ability to change default paths (loaded from paths.json file - use paths-example.json as a template).
132-
13. Ability to retain input files names (when using Image-2-Image mode).
133-
14. Ability to generate multiple images using same seed (useful in Image-2-Image mode).
134-
15. Ability to generate images forever (ported from SD web UI - right-click on Generate button to start or stop this mode).
135-
16. Ability to stop image generation.
136-
17. Official list of SDXL resolutions (as defined in [SDXL paper](https://arxiv.org/abs/2307.01952)).
137-
18. Compact resolution and style selection (thx to [runew0lf](https://github.com/runew0lf) for hints).
138-
19. Support for custom resolutions list (loaded from resolutions.json - use resolutions-example.json as a template).
139-
20. Support for custom resolutions - you can just type it now in Resolution field, like "1280x640".
140-
21. Support for custom styles (loaded from sdxl_styles folder on start).
141-
22. Support for playing audio when generation is finished (ported from SD web UI - use notification.ogg or notification.mp3).
142-
23. Starting generation via Ctrl-ENTER hotkey (ported from SD web UI).
124+
5. Adjustable text prompt strengths (useful in Revision mode).
125+
6. Support for embeddings (use "embedding:embedding_name" syntax, ComfyUI style).
126+
7. Customizable sampling parameters (sampler, scheduler, steps, base / refiner switch point, CFG, CLIP Skip).
127+
8. Displaying full metadata for generated images in the UI.
128+
9. Support for JPEG format.
129+
10. Ability to save full metadata for generated images (as JSON or embedded in image, disabled by default).
130+
11. Ability to load prompt information from JSON and image files (if saved with metadata).
131+
12. Ability to change default values of UI settings (loaded from settings.json file - use settings-example.json as a template).
132+
13. Ability to change default paths (loaded from paths.json file - use paths-example.json as a template).
133+
14. Ability to retain input files names (when using Image-2-Image mode).
134+
15. Ability to generate multiple images using same seed (useful in Image-2-Image mode).
135+
16. Ability to generate images forever (ported from SD web UI - right-click on Generate button to start or stop this mode).
136+
17. Ability to stop image generation.
137+
18. Official list of SDXL resolutions (as defined in [SDXL paper](https://arxiv.org/abs/2307.01952)).
138+
19. Compact resolution and style selection (thx to [runew0lf](https://github.com/runew0lf) for hints).
139+
20. Support for custom resolutions list (loaded from resolutions.json - use resolutions-example.json as a template).
140+
21. Support for custom resolutions - you can just type it now in Resolution field, like "1280x640".
141+
22. Support for custom styles (loaded from sdxl_styles folder on start).
142+
23. Support for playing audio when generation is finished (ported from SD web UI - use notification.ogg or notification.mp3).
143+
24. Starting generation via Ctrl-ENTER hotkey (ported from SD web UI).
143144

144145
## Thanks
145146

settings-example.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
"depth_model": "control-lora-depth-rank128.safetensors",
3232
"keep_input_names": false,
3333
"revision": false,
34-
"zero_out_positive": false,
35-
"zero_out_negative": false,
34+
"positive_prompt_strength": 1.0,
35+
"negative_prompt_strength": 1.0,
3636
"revision_strength_1": 1.0,
3737
"revision_strength_2": 1.0,
3838
"revision_strength_3": 1.0,

update_log_mre.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
### 1.0.51 MRE
22

3+
* Added support for adjusting text prompt strengths (useful in Revision mode).
34
* Updated Comfy.
45

56
### 1.0.50 MRE

webui.py

+12-8
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,14 @@ def metadata_to_ctrls(metadata, ctrls):
155155
ctrls[31] = metadata['denoise']
156156
if 'revision' in metadata:
157157
ctrls[32] = metadata['revision']
158-
if 'zero_out' in metadata:
159-
ctrls[33] = metadata['zero_out_positive']
160-
if 'zero_out' in metadata:
161-
ctrls[34] = metadata['zero_out_negative']
158+
if 'positive_prompt_strength' in metadata:
159+
ctrls[33] = metadata['positive_prompt_strength']
160+
elif 'zero_out_positive' in metadata:
161+
ctrls[33] = 0.0 if metadata['zero_out_positive'] else 1.0
162+
if 'negative_prompt_strength' in metadata:
163+
ctrls[34] = metadata['negative_prompt_strength']
164+
elif 'zero_out_negative' in metadata:
165+
ctrls[34] = 0.0 if metadata['zero_out_negative'] else 1.0
162166
if 'revision_strength_1' in metadata:
163167
ctrls[35] = metadata['revision_strength_1']
164168
if 'revision_strength_2' in metadata:
@@ -329,9 +333,9 @@ def performance_changed(value):
329333
revision_strength_2 = gr.Slider(label='Revision Strength for Image 2', minimum=-2, maximum=2, step=0.01, value=settings['revision_strength_2'])
330334
revision_strength_3 = gr.Slider(label='Revision Strength for Image 3', minimum=-2, maximum=2, step=0.01, value=settings['revision_strength_3'])
331335
revision_strength_4 = gr.Slider(label='Revision Strength for Image 4', minimum=-2, maximum=2, step=0.01, value=settings['revision_strength_4'])
332-
with gr.Row():
333-
zero_out_positive = gr.Checkbox(label='Zero Out Positive Prompt', value=settings['zero_out_positive'])
334-
zero_out_negative = gr.Checkbox(label='Zero Out Negative Prompt', value=settings['zero_out_negative'])
336+
337+
positive_prompt_strength = gr.Slider(label='Positive Prompt Strength', minimum=0, maximum=1, step=0.01, value=settings['positive_prompt_strength'])
338+
negative_prompt_strength = gr.Slider(label='Negative Prompt Strength', minimum=0, maximum=1, step=0.01, value=settings['negative_prompt_strength'])
335339

336340
img2img_start_step = gr.Slider(label='Image-2-Image Start Step', minimum=0.0, maximum=0.8, step=0.01, value=settings['img2img_start_step'])
337341
img2img_denoise = gr.Slider(label='Image-2-Image Denoise', minimum=0.2, maximum=1.0, step=0.01, value=settings['img2img_denoise'])
@@ -349,7 +353,7 @@ def performance_changed(value):
349353
output_to_input_button.click(output_to_input_handler, inputs=output_gallery, outputs=[input_gallery, gallery_tabs])
350354
output_to_revision_button.click(output_to_revision_handler, inputs=output_gallery, outputs=[revision_mode, revision_gallery, gallery_tabs])
351355

352-
img2img_ctrls = [img2img_mode, img2img_start_step, img2img_denoise, revision_mode, zero_out_positive, zero_out_negative,
356+
img2img_ctrls = [img2img_mode, img2img_start_step, img2img_denoise, revision_mode, positive_prompt_strength, negative_prompt_strength,
353357
revision_strength_1, revision_strength_2, revision_strength_3, revision_strength_4]
354358

355359
def verify_revision(rev, gallery_in, gallery_rev, gallery_out):

0 commit comments

Comments
 (0)