Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
chenpangpang
ComfyUI
Commits
45ec1cbe
Commit
45ec1cbe
authored
Apr 16, 2024
by
comfyanonymous
Browse files
Implement PerpNeg as a guider.
parent
8903dce8
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
54 additions
and
8 deletions
+54
-8
comfy_extras/nodes_perpneg.py
comfy_extras/nodes_perpneg.py
+54
-8
No files found.
comfy_extras/nodes_perpneg.py
View file @
45ec1cbe
...
@@ -3,9 +3,18 @@ import comfy.model_management
...
@@ -3,9 +3,18 @@ import comfy.model_management
import
comfy.sampler_helpers
import
comfy.sampler_helpers
import
comfy.samplers
import
comfy.samplers
import
comfy.utils
import
comfy.utils
import
node_helpers
def
perp_neg
(
x
,
noise_pred_pos
,
noise_pred_neg
,
noise_pred_nocond
,
neg_scale
,
cond_scale
):
pos
=
noise_pred_pos
-
noise_pred_nocond
neg
=
noise_pred_neg
-
noise_pred_nocond
#TODO: This node should be removed and replaced with one that uses the new Guider/SamplerCustomAdvanced.
perp
=
neg
-
((
torch
.
mul
(
neg
,
pos
).
sum
())
/
(
torch
.
norm
(
pos
)
**
2
))
*
pos
perp_neg
=
perp
*
neg_scale
cfg_result
=
noise_pred_nocond
+
cond_scale
*
(
pos
-
perp_neg
)
return
cfg_result
#TODO: This node should be removed, it has been replaced with PerpNegGuider
class
PerpNeg
:
class
PerpNeg
:
@
classmethod
@
classmethod
def
INPUT_TYPES
(
s
):
def
INPUT_TYPES
(
s
):
...
@@ -34,12 +43,7 @@ class PerpNeg:
...
@@ -34,12 +43,7 @@ class PerpNeg:
(
noise_pred_nocond
,)
=
comfy
.
samplers
.
calc_cond_batch
(
model
,
[
nocond_processed
],
x
,
sigma
,
model_options
)
(
noise_pred_nocond
,)
=
comfy
.
samplers
.
calc_cond_batch
(
model
,
[
nocond_processed
],
x
,
sigma
,
model_options
)
pos
=
noise_pred_pos
-
noise_pred_nocond
cfg_result
=
x
-
perp_neg
(
x
,
noise_pred_pos
,
noise_pred_neg
,
noise_pred_nocond
,
neg_scale
,
cond_scale
)
neg
=
noise_pred_neg
-
noise_pred_nocond
perp
=
neg
-
((
torch
.
mul
(
neg
,
pos
).
sum
())
/
(
torch
.
norm
(
pos
)
**
2
))
*
pos
perp_neg
=
perp
*
neg_scale
cfg_result
=
noise_pred_nocond
+
cond_scale
*
(
pos
-
perp_neg
)
cfg_result
=
x
-
cfg_result
return
cfg_result
return
cfg_result
m
.
set_model_sampler_cfg_function
(
cfg_function
)
m
.
set_model_sampler_cfg_function
(
cfg_function
)
...
@@ -47,10 +51,52 @@ class PerpNeg:
...
@@ -47,10 +51,52 @@ class PerpNeg:
return
(
m
,
)
return
(
m
,
)
class
Guider_PerpNeg
(
comfy
.
samplers
.
CFGGuider
):
def
set_conds
(
self
,
positive
,
negative
,
empty_negative_prompt
):
empty_negative_prompt
=
node_helpers
.
conditioning_set_values
(
empty_negative_prompt
,
{
"prompt_type"
:
"negative"
})
self
.
inner_set_conds
({
"positive"
:
positive
,
"empty_negative_prompt"
:
empty_negative_prompt
,
"negative"
:
negative
})
def
set_cfg
(
self
,
cfg
,
neg_scale
):
self
.
cfg
=
cfg
self
.
neg_scale
=
neg_scale
def
predict_noise
(
self
,
x
,
timestep
,
model_options
=
{},
seed
=
None
):
positive_cond
=
self
.
conds
.
get
(
"positive"
,
None
)
negative_cond
=
self
.
conds
.
get
(
"negative"
,
None
)
empty_cond
=
self
.
conds
.
get
(
"empty_negative_prompt"
,
None
)
out
=
comfy
.
samplers
.
calc_cond_batch
(
self
.
inner_model
,
[
negative_cond
,
positive_cond
,
empty_cond
],
x
,
timestep
,
model_options
)
return
perp_neg
(
x
,
out
[
1
],
out
[
0
],
out
[
2
],
self
.
neg_scale
,
self
.
cfg
)
class
PerpNegGuider
:
@
classmethod
def
INPUT_TYPES
(
s
):
return
{
"required"
:
{
"model"
:
(
"MODEL"
,),
"positive"
:
(
"CONDITIONING"
,
),
"negative"
:
(
"CONDITIONING"
,
),
"empty_conditioning"
:
(
"CONDITIONING"
,
),
"cfg"
:
(
"FLOAT"
,
{
"default"
:
8.0
,
"min"
:
0.0
,
"max"
:
100.0
,
"step"
:
0.1
,
"round"
:
0.01
}),
"neg_scale"
:
(
"FLOAT"
,
{
"default"
:
1.0
,
"min"
:
0.0
,
"max"
:
100.0
,
"step"
:
0.01
}),
}
}
RETURN_TYPES
=
(
"GUIDER"
,)
FUNCTION
=
"get_guider"
CATEGORY
=
"_for_testing"
def
get_guider
(
self
,
model
,
positive
,
negative
,
empty_conditioning
,
cfg
,
neg_scale
):
guider
=
Guider_PerpNeg
(
model
)
guider
.
set_conds
(
positive
,
negative
,
empty_conditioning
)
guider
.
set_cfg
(
cfg
,
neg_scale
)
return
(
guider
,)
NODE_CLASS_MAPPINGS
=
{
NODE_CLASS_MAPPINGS
=
{
"PerpNeg"
:
PerpNeg
,
"PerpNeg"
:
PerpNeg
,
"PerpNegGuider"
:
PerpNegGuider
,
}
}
NODE_DISPLAY_NAME_MAPPINGS
=
{
NODE_DISPLAY_NAME_MAPPINGS
=
{
"PerpNeg"
:
"Perp-Neg"
,
"PerpNeg"
:
"Perp-Neg
(DEPRECATED by PerpNegGuider)
"
,
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment