57 lines
1.9 KiB
Python
57 lines
1.9 KiB
Python
import torch
|
|
|
|
|
|
def _rejection(u, v):
|
|
uv = torch.mean(u * v, dim=list(range(1, v.ndim)), keepdim=True)
|
|
vv = torch.mean(v ** 2, dim=list(range(1, v.ndim)), keepdim=True) + 1.0e-05
|
|
return u - (uv / vv) * v
|
|
|
|
|
|
def _normalize(u, v):
|
|
uu = torch.mean(u ** 2, dim=list(range(1, u.ndim)), keepdim=True) + 1.0e-05
|
|
vv = torch.mean(v ** 2, dim=list(range(1, v.ndim)), keepdim=True)
|
|
return ((torch.relu(1 - vv) / uu) ** 0.5) * u
|
|
|
|
|
|
class PredictionBoost:
|
|
@classmethod
|
|
def INPUT_TYPES(s):
|
|
return {
|
|
"required": {
|
|
"model": ("MODEL",),
|
|
"version": (["24.03", "24.05", "24.07"], ),
|
|
"boost_scale": ("FLOAT", {"default": 0.0, "min": -1.0, "max": 1.0, "step": 0.01}),
|
|
},
|
|
}
|
|
|
|
RETURN_TYPES = ("MODEL",)
|
|
FUNCTION = "execute"
|
|
CATEGORY = "advanced/model"
|
|
|
|
def execute(self, model, boost_scale, version="24.05"):
|
|
def sampler_post_cfg_function(args):
|
|
sigma = args["sigma"]
|
|
input = args["input"]
|
|
denoised = args["denoised"]
|
|
cond_denoised = args["cond_denoised"]
|
|
|
|
noise_pred = (input - denoised) / sigma
|
|
noise_pred_cond = (input - cond_denoised) / sigma
|
|
if version == "off":
|
|
boost_denoised = 0
|
|
elif version == "24.03":
|
|
boost_denoised = _rejection(input, noise_pred)
|
|
elif version == "24.05":
|
|
boost_denoised = _rejection(input, noise_pred_cond)
|
|
boost_denoised = _normalize(boost_denoised, noise_pred) * sigma
|
|
elif version == "24.07":
|
|
boost_denoised = _rejection(input, noise_pred)
|
|
boost_denoised = _normalize(boost_denoised, noise_pred) * sigma
|
|
|
|
return denoised + boost_scale * boost_denoised
|
|
|
|
m = model.clone()
|
|
m.set_model_sampler_post_cfg_function(sampler_post_cfg_function)
|
|
return (m, )
|
|
|