Allow overriding noise_sampler + reduce code duplication

This commit is contained in:
blepping
2024-03-10 05:50:36 -06:00
parent b609db0df7
commit b6610d3c01
3 changed files with 133 additions and 201 deletions
+3
View File
@@ -0,0 +1,3 @@
*.bak
*~
__pycache__
+115 -120
View File
@@ -4,6 +4,7 @@ import torch
from torch import nn, FloatTensor from torch import nn, FloatTensor
import torchsde import torchsde
from tqdm.auto import trange, tqdm from tqdm.auto import trange, tqdm
import numpy as np
import comfy.sample import comfy.sample
@@ -45,12 +46,33 @@ def add_schedulers():
import importlib import importlib
importlib.reload(k_diffusion_sampling) importlib.reload(k_diffusion_sampling)
# Noise samplers # Noise samplers
NOISE_SAMPLER_NAMES=("gaussian", "uniform", "brownian", "highres-pyramid", "pyramid", "perlin", "laplacian")
def get_noise_sampler_names(default=None):
if not default:
return NOISE_SAMPLER_NAMES
return (default,) + tuple(n for n in NOISE_SAMPLER_NAMES if n != default)
def mk_noise_sampler(x, fun):
return lambda _sigma, _sigma_next: fun(x)
def get_noise_sampler(x, sigmas, noise_sampler_type="brownian", extra_args=None, cpu=False):
if noise_sampler_type == "brownian":
seed = extra_args.get("seed", None) if extra_args else None
sigma_min, sigma_max = sigmas[sigmas > 0].min(), sigmas.max()
return BrownianTreeNoiseSampler(x, sigma_min, sigma_max, seed=seed, cpu=cpu)
return mk_noise_sampler(x, NOISE_SAMPLER_HANDLERS.get(noise_sampler_type, uniform_noise_like))
from torch import Generator, Tensor, lerp from torch import Generator, Tensor, lerp
from torch.nn.functional import unfold from torch.nn.functional import unfold
from typing import Callable, Tuple from typing import Callable, Tuple
from math import pi from math import pi
def uniform_noise_like(x):
return (torch.rand_like(x) - 0.5) * 2 * 1.73
def get_positions(block_shape: Tuple[int, int]) -> Tensor: def get_positions(block_shape: Tuple[int, int]) -> Tensor:
""" """
Generate position tensor. Generate position tensor.
@@ -307,7 +329,8 @@ def green_noise_sampler(x): # This doesn't work properly right now
print(noise) print(noise)
return lambda sigma, sigma_next: noise return lambda sigma, sigma_next: noise
def power_noise_sampler(tensor, alpha=2, k=1): # This doesn't work properly right now # I'm not sure how this differs from the other implementation but it doesn't seem to be used at present.
def power_noise_sampler_2(tensor, alpha=2, k=1): # This doesn't work properly right now
"""Generate 1/f noise for a given tensor. """Generate 1/f noise for a given tensor.
Args: Args:
@@ -330,6 +353,83 @@ def power_noise_sampler(tensor, alpha=2, k=1): # This doesn't work properly righ
print(variance) print(variance)
return lambda sigma, sigma_next: noise / 3 return lambda sigma, sigma_next: noise / 3
def pyramid_noise_like(size, dtype, layout, generator, device="cpu", discount=0.8):
b, c, h, w = size
orig_h = h
orig_w = w
noise = torch.zeros(size=size, dtype=dtype, layout=layout, device=device)
r = 1
for i in range(5):
r *= 2 # Rather than always going 2x,
#w, h = max(1, int(w/(r**i))), max(1, int(h/(r**i)))
noise += torch.nn.functional.interpolate((torch.normal(mean=0, std=0.5 ** i, size=(b, c, h * r, w * r), dtype=dtype, layout=layout, generator=generator, device=device)), size=(orig_h, orig_w), mode='nearest-exact') * discount**i
#if w>=orig_w*16 or h>=orig_h*16: break
return noise
def power_noise_sampler(size, dtype, layout, generator, device="cpu", alpha=2, k=1): # This doesn't work properly right now
"""Generate 1/f noise for a given tensor.
Args:
tensor: The tensor to add noise to.
alpha: The parameter that determines the slope of the spectrum.
k: A constant.
Returns:
A tensor with the same shape as `tensor` containing 1/f noise.
"""
tensor = torch.randn(size=size, dtype=dtype, layout=layout, generator=generator, device=device)
fft = torch.fft.fft2(tensor)
freq = torch.arange(1, len(fft) + 1, dtype=torch.float)
spectral_density = k / freq**alpha
noise = torch.rand(size=size, dtype=dtype, layout=layout, generator=generator, device=device) * spectral_density
mean = torch.mean(noise, dim=(-2, -1), keepdim=True).to(tensor.device)
std = torch.std(noise, dim=(-2, -1), keepdim=True).to(tensor.device)
noise = noise.to(tensor.device).sub_(mean).div_(std)
return noise
def prepare_noise(latent_image, seed, noise_type, noise_inds=None): # From `sample.py`
"""
creates random noise given a latent image and a seed.
optional arg skip can be used to skip and discard x number of noise generations for a given seed
"""
generator = torch.manual_seed(seed)
match noise_type:
case "gaussian":
noise_func = torch.randn
case "uniform":
def uniform_rand(*size, **kwargs):
return (torch.rand(*size, **kwargs) - 0.5) * 2 * 1.73
noise_func = uniform_rand
case "pyramid":
noise_func = pyramid_noise_like
case "power":
noise_func = power_noise_sampler
case _:
noise_func = torch.randn
if noise_inds is None:
return noise_func(latent_image.size(), dtype=latent_image.dtype, layout=latent_image.layout, generator=generator, device="cpu")
unique_inds, inverse = np.unique(noise_inds, return_inverse=True)
noises = []
for i in range(unique_inds[-1]+1):
noise = noise_func([1] + list(latent_image.size())[1:], dtype=latent_image.dtype, layout=latent_image.layout, generator=generator, device="cpu")
if i in unique_inds:
noises.append(noise)
noises = [noises[i] for i in inverse]
noises = torch.cat(noises, axis=0)
return noises
NOISE_SAMPLER_HANDLERS={
# Brownian is special-cased.
"gaussian": torch.randn_like,
"highres-pyramid": highres_pyramid_noise_like,
"pyramid": lambda x: pyramid_noise_like(x.size(), x.dtype, x.layout, None, device=x.device),
"perlin": rand_perlin_like,
"laplacian": rand_laplacian_like,
"uniform": uniform_noise_like,
}
# Below this point are extra samplers # Below this point are extra samplers
@torch.no_grad() @torch.no_grad()
def sample_clyb_4m_sde_momentumized(model, x, sigmas, extra_args=None, callback=None, disable=None, eta=1.0, s_noise=1., noise_sampler=None, momentum=0.0): def sample_clyb_4m_sde_momentumized(model, x, sigmas, extra_args=None, callback=None, disable=None, eta=1.0, s_noise=1., noise_sampler=None, momentum=0.0):
@@ -462,25 +562,8 @@ def sample_ttm_jvp(model, x, sigmas, extra_args=None, callback=None, disable=Non
# Many thanks to Kat + Birch-San for this wonderful sampler implementation! https://github.com/Birch-san/sdxl-play/commits/res/ # Many thanks to Kat + Birch-San for this wonderful sampler implementation! https://github.com/Birch-san/sdxl-play/commits/res/
from .other_samplers.refined_exp_solver import sample_refined_exp_s from .other_samplers.refined_exp_solver import sample_refined_exp_s
def sample_res_solver(model, x, sigmas, extra_args=None, callback=None, disable=None, noise_sampler=None, denoise_to_zero=True, simple_phi_calc=False, c2=0.5, ita=torch.Tensor((0.25,)), momentum=0.0): def sample_res_solver(model, x, sigmas, extra_args=None, callback=None, disable=None, noise_sampler_type="gaussian", noise_sampler=None, denoise_to_zero=True, simple_phi_calc=False, c2=0.5, ita=torch.Tensor((0.25,)), momentum=0.0):
sigma_min, sigma_max = sigmas[sigmas > 0].min(), sigmas.max() return sample_refined_exp_s(model, x, sigmas, extra_args=extra_args, callback=callback, disable=disable, noise_sampler=noise_sampler or get_noise_sampler(x, sigmas, noise_sampler_type, noise_sampler, extra_args), denoise_to_zero=denoise_to_zero, simple_phi_calc=simple_phi_calc, c2=c2, ita=ita, momentum=momentum)
seed = extra_args.get("seed", None)
match noise_sampler:
case "brownian":
noise_sampler = BrownianTreeNoiseSampler(x, sigma_min, sigma_max, seed=seed, cpu=False)
case "gaussian":
noise_sampler = lambda sigma, sigma_next: torch.randn_like(x)
case "uniform":
noise_sampler = lambda sigma, sigma_next: (torch.rand_like(x) - 0.5) * 2 * 1.73
case "highres-pyramid":
noise_sampler = lambda sigma, sigma_next: highres_pyramid_noise_like(x)
case "perlin":
noise_sampler = lambda sigma, sigma_next: rand_perlin_like(x)
case "laplacian":
noise_sampler = lambda sigma, sigma_next: rand_laplacian_like(x)
case _:
noise_sampler = lambda sigma, sigma_next: torch.randn_like(x)
return sample_refined_exp_s(model, x, sigmas, extra_args=extra_args, callback=callback, disable=disable, noise_sampler=noise_sampler, denoise_to_zero=denoise_to_zero, simple_phi_calc=simple_phi_calc, c2=c2, ita=ita, momentum=momentum)
@torch.no_grad() @torch.no_grad()
def sample_dpmpp_dualsde_momentum(model, x, sigmas, extra_args=None, callback=None, disable=None, eta=1., s_noise=1., noise_sampler=None, r=1/2, momentum=0.0): def sample_dpmpp_dualsde_momentum(model, x, sigmas, extra_args=None, callback=None, disable=None, eta=1., s_noise=1., noise_sampler=None, r=1/2, momentum=0.0):
@@ -582,73 +665,19 @@ def sample_dpmpp_dualsde_momentum(model, x, sigmas, extra_args=None, callback=No
h_1, h_2, h_3 = h, h_1, h_2 h_1, h_2, h_3 = h, h_1, h_2
return x return x
def sample_dpmpp_dualsdemomentum(model, x, sigmas, extra_args=None, callback=None, disable=None, eta=1., s_noise=1., noise_sampler=None, r=1/2, momentum=0.0): def sample_dpmpp_dualsdemomentum(model, x, sigmas, extra_args=None, callback=None, disable=None, eta=1., s_noise=1., noise_sampler_type="gaussian", noise_sampler=None, r=1/2, momentum=0.0):
sigma_min, sigma_max = sigmas[sigmas > 0].min(), sigmas.max() return sample_dpmpp_dualsde_momentum(model, x, sigmas, extra_args=extra_args, callback=callback, disable=disable, eta=eta, s_noise=s_noise, noise_sampler=noise_sampler or get_noise_sampler(x, sigmas, noise_sampler_type, noise_sampler, extra_args), r=r, momentum=momentum)
seed = extra_args.get("seed", None)
match noise_sampler:
case "brownian":
noise_sampler = BrownianTreeNoiseSampler(x, sigma_min, sigma_max, seed=seed, cpu=False)
case "gaussian":
noise_sampler = lambda sigma, sigma_next: torch.randn_like(x)
case "uniform":
noise_sampler = lambda sigma, sigma_next: (torch.rand_like(x) - 0.5) * 2 * 1.73
case "perlin":
noise_sampler = lambda sigma, sigma_next: rand_perlin_like(x)
case "laplacian":
noise_sampler = lambda sigma, sigma_next: rand_laplacian_like(x)
case _:
noise_sampler = lambda sigma, sigma_next: torch.randn_like(x)
return sample_dpmpp_dualsde_momentum(model, x, sigmas, extra_args=extra_args, callback=callback, disable=disable, eta=eta, s_noise=s_noise, noise_sampler=noise_sampler, r=r, momentum=momentum)
from .other_samplers.sample_ttm import sample_ttm_jvp from .other_samplers.sample_ttm import sample_ttm_jvp
def sample_ttmcustom(model, x, sigmas, extra_args=None, callback=None, disable=None, eta=1., s_noise=1., noise_sampler=None): def sample_ttmcustom(model, x, sigmas, extra_args=None, callback=None, disable=None, eta=1., s_noise=1., noise_sampler_type="gaussian",noise_sampler=None):
sigma_min, sigma_max = sigmas[sigmas > 0].min(), sigmas.max() return sample_ttm_jvp(model, x, sigmas, extra_args=extra_args, callback=callback, disable=disable, eta=eta, s_noise=s_noise, noise_sampler=noise_sampler or get_noise_sampler(x, sigmas, noise_sampler_type, noise_sampler, extra_args))
seed = extra_args.get("seed", None)
match noise_sampler:
case "gaussian":
noise_sampler = lambda sigma, sigma_next: torch.randn_like(x)
case "uniform":
noise_sampler = lambda sigma, sigma_next: (torch.rand_like(x) - 0.5) * 2 * 1.73
case "brownian":
noise_sampler = BrownianTreeNoiseSampler(x, sigma_min, sigma_max, seed=seed, cpu=False)
case _:
noise_sampler = lambda sigma, sigma_next: torch.randn_like(x)
return sample_ttm_jvp(model, x, sigmas, extra_args=extra_args, callback=callback, disable=disable, eta=eta, s_noise=s_noise, noise_sampler=noise_sampler)
from comfy.k_diffusion.sampling import sample_lcm from comfy.k_diffusion.sampling import sample_lcm
def sample_lcmcustom(model, x, sigmas, extra_args=None, callback=None, disable=None, noise_sampler=None): def sample_lcmcustom(model, x, sigmas, extra_args=None, callback=None, disable=None, noise_sampler_type="gaussian", noise_sampler=None):
sigma_min, sigma_max = sigmas[sigmas > 0].min(), sigmas.max() return sample_lcm(model, x, sigmas, extra_args=extra_args, callback=callback, disable=disable, noise_sampler=noise_sampler or get_noise_sampler(x, sigmas, noise_sampler_type, noise_sampler, extra_args))
seed = extra_args.get("seed", None)
match noise_sampler:
case "gaussian":
noise_sampler = lambda sigma, sigma_next: torch.randn_like(x)
case "uniform":
noise_sampler = lambda sigma, sigma_next: (torch.rand_like(x) - 0.5) * 2 * 1.73
case "brownian":
noise_sampler = BrownianTreeNoiseSampler(x, sigma_min, sigma_max, seed=seed, cpu=False)
case _:
noise_sampler = lambda sigma, sigma_next: torch.randn_like(x)
return sample_lcm(model, x, sigmas, extra_args=extra_args, callback=callback, disable=disable, noise_sampler=noise_sampler)
def sample_clyb_4m_sde(model, x, sigmas, extra_args=None, callback=None, disable=None, eta=1., s_noise=1., noise_sampler="brownian", momentum=0.0): def sample_clyb_4m_sde(model, x, sigmas, extra_args=None, callback=None, disable=None, eta=1., s_noise=1., noise_sampler_type="brownian", noise_sampler=None, momentum=0.0):
sigma_min, sigma_max = sigmas[sigmas > 0].min(), sigmas.max() return sample_clyb_4m_sde_momentumized(model, x, sigmas, extra_args=extra_args, callback=callback, disable=disable, eta=eta, s_noise=s_noise, noise_sampler=noise_sampler or get_noise_sampler(x, sigmas, noise_sampler_type, noise_sampler, extra_args), momentum=momentum)
seed = extra_args.get("seed", None)
match noise_sampler:
case "brownian":
noise_sampler = BrownianTreeNoiseSampler(x, sigma_min, sigma_max, seed=seed, cpu=False)
case "gaussian":
noise_sampler = lambda sigma, sigma_next: torch.randn_like(x)
case "uniform":
noise_sampler = lambda sigma, sigma_next: (torch.rand_like(x) - 0.5) * 2 * 1.73
case "highres-pyramid":
noise_sampler = lambda sigma, sigma_next: highres_pyramid_noise_like(x)
case "perlin":
noise_sampler = lambda sigma, sigma_next: rand_perlin_like(x)
case "laplacian":
noise_sampler = lambda sigma, sigma_next: rand_laplacian_like(x)
case _:
noise_sampler = lambda sigma, sigma_next: (torch.rand_like(x) - 0.5) * 2 * 1.73
return sample_clyb_4m_sde_momentumized(model, x, sigmas, extra_args=extra_args, callback=callback, disable=disable, eta=eta, s_noise=s_noise, noise_sampler=noise_sampler, momentum=momentum)
# This code works, but I'm currently experimenting with different methods # This code works, but I'm currently experimenting with different methods
@@ -698,25 +727,8 @@ def sampler_euler_ancestral_dancing(model, x, sigmas, extra_args=None, callback=
return x return x
def sample_euler_ancestral_dancing(model, x, sigmas, extra_args=None, callback=None, disable=None, eta=1., s_noise=1., noise_sampler="gaussian", leap=2, eta_dance=1.0): def sample_euler_ancestral_dancing(model, x, sigmas, extra_args=None, callback=None, disable=None, eta=1., s_noise=1., noise_sampler_type="gaussian", noise_sampler=None, leap=2, eta_dance=1.0):
sigma_min, sigma_max = sigmas[sigmas > 0].min(), sigmas.max() return sampler_euler_ancestral_dancing(model, x, sigmas, extra_args=extra_args, callback=callback, disable=disable, eta=eta, s_noise=s_noise, noise_sampler=noise_sampler or get_noise_sampler(x, sigmas, noise_sampler_type, noise_sampler, extra_args), leap=leap, eta_dance=eta_dance)
seed = extra_args.get("seed", None)
match noise_sampler:
case "brownian":
noise_sampler = BrownianTreeNoiseSampler(x, sigma_min, sigma_max, seed=seed, cpu=False)
case "gaussian":
noise_sampler = lambda sigma, sigma_next: torch.randn_like(x)
case "uniform":
noise_sampler = lambda sigma, sigma_next: (torch.rand_like(x) - 0.5) * 2 * 1.73
case "highres-pyramid":
noise_sampler = lambda sigma, sigma_next: highres_pyramid_noise_like(x)
case "perlin":
noise_sampler = lambda sigma, sigma_next: rand_perlin_like(x)
case "laplacian":
noise_sampler = lambda sigma, sigma_next: rand_laplacian_like(x)
case _:
noise_sampler = lambda sigma, sigma_next: (torch.rand_like(x) - 0.5) * 2 * 1.73
return sampler_euler_ancestral_dancing(model, x, sigmas, extra_args=extra_args, callback=callback, disable=disable, eta=eta, s_noise=s_noise, noise_sampler=noise_sampler, leap=leap, eta_dance=eta_dance)
@torch.no_grad() @torch.no_grad()
@@ -778,25 +790,8 @@ def sampler_dpmpp_3m_sde_dynamic_eta(model, x, sigmas, extra_args=None, callback
h_1, h_2 = h, h_1 h_1, h_2 = h, h_1
return x return x
def sample_dpmpp_3m_sde_dynamic_eta(model, x, sigmas, extra_args=None, callback=None, disable=None, eta_max=1.0, eta_min=0.0, s_noise=1., noise_sampler="brownian"): def sample_dpmpp_3m_sde_dynamic_eta(model, x, sigmas, extra_args=None, callback=None, disable=None, eta_max=1.0, eta_min=0.0, s_noise=1., noise_sampler_type="brownian", noise_sampler=None):
sigma_min, sigma_max = sigmas[sigmas > 0].min(), sigmas.max() return sampler_dpmpp_3m_sde_dynamic_eta(model, x, sigmas, extra_args=extra_args, callback=callback, disable=disable, eta_max=eta_max, eta_min=eta_min, s_noise=s_noise, noise_sampler=noise_sampler or get_noise_sampler(x, sigmas, noise_sampler_type, noise_sampler, extra_args))
seed = extra_args.get("seed", None)
match noise_sampler:
case "brownian":
noise_sampler = BrownianTreeNoiseSampler(x, sigma_min, sigma_max, seed=seed, cpu=False)
case "gaussian":
noise_sampler = lambda sigma, sigma_next: torch.randn_like(x)
case "uniform":
noise_sampler = lambda sigma, sigma_next: (torch.rand_like(x) - 0.5) * 2 * 1.73
case "highres-pyramid":
noise_sampler = lambda sigma, sigma_next: highres_pyramid_noise_like(x)
case "perlin":
noise_sampler = lambda sigma, sigma_next: rand_perlin_like(x)
case "laplacian":
noise_sampler = lambda sigma, sigma_next: rand_laplacian_like(x)
case _:
noise_sampler = lambda sigma, sigma_next: (torch.rand_like(x) - 0.5) * 2 * 1.73
return sampler_dpmpp_3m_sde_dynamic_eta(model, x, sigmas, extra_args=extra_args, callback=callback, disable=disable, eta_max=eta_max, eta_min=eta_min, s_noise=s_noise, noise_sampler=noise_sampler)
# Add your personal samplers below here, just for formatting purposes ;3 # Add your personal samplers below here, just for formatting purposes ;3
+15 -81
View File
@@ -1,83 +1,17 @@
from .other_samplers.refined_exp_solver import sample_refined_exp_s from .other_samplers.refined_exp_solver import sample_refined_exp_s
from .extra_samplers import get_noise_sampler_names, prepare_noise
import comfy.samplers import comfy.samplers
import comfy.sample import comfy.sample
from comfy.k_diffusion import sampling as k_diffusion_sampling from comfy.k_diffusion import sampling as k_diffusion_sampling
import latent_preview import latent_preview
import torch import torch
import numpy as np
from tqdm.auto import trange from tqdm.auto import trange
def pyramid_noise_like(size, dtype, layout, generator, device="cpu", discount=0.8):
b, c, h, w = size
orig_h = h
orig_w = w
noise = torch.zeros(size=size, dtype=dtype, layout=layout, device=device)
r = 1
for i in range(5):
r *= 2 # Rather than always going 2x,
#w, h = max(1, int(w/(r**i))), max(1, int(h/(r**i)))
noise += torch.nn.functional.interpolate((torch.normal(mean=0, std=0.5 ** i, size=(b, c, h * r, w * r), dtype=dtype, layout=layout, generator=generator, device=device)), size=(orig_h, orig_w), mode='nearest-exact') * discount**i
#if w>=orig_w*16 or h>=orig_h*16: break
return noise
def power_noise_sampler(size, dtype, layout, generator, device="cpu", alpha=2, k=1): # This doesn't work properly right now
"""Generate 1/f noise for a given tensor.
Args:
tensor: The tensor to add noise to.
alpha: The parameter that determines the slope of the spectrum.
k: A constant.
Returns:
A tensor with the same shape as `tensor` containing 1/f noise.
"""
tensor = torch.randn(size=size, dtype=dtype, layout=layout, generator=generator, device=device)
fft = torch.fft.fft2(tensor)
freq = torch.arange(1, len(fft) + 1, dtype=torch.float)
spectral_density = k / freq**alpha
noise = torch.rand(size=size, dtype=dtype, layout=layout, generator=generator, device=device) * spectral_density
mean = torch.mean(noise, dim=(-2, -1), keepdim=True).to(tensor.device)
std = torch.std(noise, dim=(-2, -1), keepdim=True).to(tensor.device)
noise = noise.to(tensor.device).sub_(mean).div_(std)
return noise
def prepare_noise(latent_image, seed, noise_type, noise_inds=None): # From `sample.py`
"""
creates random noise given a latent image and a seed.
optional arg skip can be used to skip and discard x number of noise generations for a given seed
"""
generator = torch.manual_seed(seed)
match noise_type:
case "gaussian":
noise_func = torch.randn
case "uniform":
def uniform_rand(*size, **kwargs):
return (torch.rand(*size, **kwargs) - 0.5) * 2 * 1.73
noise_func = uniform_rand
case "pyramid":
noise_func = pyramid_noise_like
case "power":
noise_func = power_noise_sampler
case _:
noise_func = torch.randn
if noise_inds is None:
return noise_func(latent_image.size(), dtype=latent_image.dtype, layout=latent_image.layout, generator=generator, device="cpu")
unique_inds, inverse = np.unique(noise_inds, return_inverse=True)
noises = []
for i in range(unique_inds[-1]+1):
noise = noise_func([1] + list(latent_image.size())[1:], dtype=latent_image.dtype, layout=latent_image.layout, generator=generator, device="cpu")
if i in unique_inds:
noises.append(noise)
noises = [noises[i] for i in inverse]
noises = torch.cat(noises, axis=0)
return noises
class SamplerRES_MOMENTUMIZED: class SamplerRES_MOMENTUMIZED:
@classmethod @classmethod
def INPUT_TYPES(s): def INPUT_TYPES(s):
return {"required": return {"required":
{"noise_sampler_type": (["gaussian", "uniform", "brownian", "highres-pyramid", "perlin", "laplacian"], ), {"noise_sampler_type": (get_noise_sampler_names(), ),
"momentum": ("FLOAT", {"default": 0.5, "min": -1.0, "max": 1.0, "step":0.01}), "momentum": ("FLOAT", {"default": 0.5, "min": -1.0, "max": 1.0, "step":0.01}),
"denoise_to_zero": ("BOOLEAN", {"default": True}), "denoise_to_zero": ("BOOLEAN", {"default": True}),
"simple_phi_calc": ("BOOLEAN", {"default": False}), "simple_phi_calc": ("BOOLEAN", {"default": False}),
@@ -91,14 +25,14 @@ class SamplerRES_MOMENTUMIZED:
FUNCTION = "get_sampler" FUNCTION = "get_sampler"
def get_sampler(self, noise_sampler_type, momentum, denoise_to_zero, simple_phi_calc, ita, c2): def get_sampler(self, noise_sampler_type, momentum, denoise_to_zero, simple_phi_calc, ita, c2):
sampler = comfy.samplers.ksampler("res_momentumized", {"noise_sampler": noise_sampler_type, "denoise_to_zero": denoise_to_zero, "simple_phi_calc": simple_phi_calc, "c2": c2, "ita": torch.Tensor((ita,)), "momentum": momentum}) sampler = comfy.samplers.ksampler("res_momentumized", {"noise_sampler_type": noise_sampler_type, "denoise_to_zero": denoise_to_zero, "simple_phi_calc": simple_phi_calc, "c2": c2, "ita": torch.Tensor((ita,)), "momentum": momentum})
return (sampler, ) return (sampler, )
class SamplerDPMPP_DUALSDE_MOMENTUMIZED: class SamplerDPMPP_DUALSDE_MOMENTUMIZED:
@classmethod @classmethod
def INPUT_TYPES(s): def INPUT_TYPES(s):
return {"required": return {"required":
{"noise_sampler_type": (["gaussian", "uniform", "brownian", "perlin", "laplacian"], ), {"noise_sampler_type": (get_noise_sampler_names(), ),
"momentum": ("FLOAT", {"default": 0.5, "min": -1.0, "max": 1.0, "step":0.01}), "momentum": ("FLOAT", {"default": 0.5, "min": -1.0, "max": 1.0, "step":0.01}),
"eta": ("FLOAT", {"default": 1, "min": 0.0, "max": 100.0, "step":0.01}), "eta": ("FLOAT", {"default": 1, "min": 0.0, "max": 100.0, "step":0.01}),
"s_noise": ("FLOAT", {"default": 1, "min": 0.0, "max": 100.0, "step":0.01}), "s_noise": ("FLOAT", {"default": 1, "min": 0.0, "max": 100.0, "step":0.01}),
@@ -111,14 +45,14 @@ class SamplerDPMPP_DUALSDE_MOMENTUMIZED:
FUNCTION = "get_sampler" FUNCTION = "get_sampler"
def get_sampler(self, noise_sampler_type, momentum, eta, s_noise, r,): def get_sampler(self, noise_sampler_type, momentum, eta, s_noise, r,):
sampler = comfy.samplers.ksampler("dpmpp_dualsde_momentumized", {"noise_sampler": noise_sampler_type, "eta": eta, "s_noise": s_noise, "r": r, "momentum": momentum}) sampler = comfy.samplers.ksampler("dpmpp_dualsde_momentumized", {"noise_sampler_type": noise_sampler_type, "eta": eta, "s_noise": s_noise, "r": r, "momentum": momentum})
return (sampler, ) return (sampler, )
class SamplerTTM: class SamplerTTM:
@classmethod @classmethod
def INPUT_TYPES(s): def INPUT_TYPES(s):
return {"required": return {"required":
{"noise_sampler_type": (["gaussian", "uniform", "brownian"], ), {"noise_sampler_type": (get_noise_sampler_names(), ),
"eta": ("FLOAT", {"default": 1, "min": 0.0, "max": 100.0, "step":0.01}), "eta": ("FLOAT", {"default": 1, "min": 0.0, "max": 100.0, "step":0.01}),
"s_noise": ("FLOAT", {"default": 1, "min": 0.0, "max": 100.0, "step":0.01}), "s_noise": ("FLOAT", {"default": 1, "min": 0.0, "max": 100.0, "step":0.01}),
} }
@@ -129,7 +63,7 @@ class SamplerTTM:
FUNCTION = "get_sampler" FUNCTION = "get_sampler"
def get_sampler(self, noise_sampler_type, eta, s_noise): def get_sampler(self, noise_sampler_type, eta, s_noise):
sampler = comfy.samplers.ksampler("ttm", {"noise_sampler": noise_sampler_type, "eta": eta, "s_noise": s_noise}) sampler = comfy.samplers.ksampler("ttm", {"noise_sampler_type": noise_sampler_type, "eta": eta, "s_noise": s_noise})
return (sampler, ) return (sampler, )
@@ -137,7 +71,7 @@ class SamplerLCMCustom:
@classmethod @classmethod
def INPUT_TYPES(s): def INPUT_TYPES(s):
return {"required": return {"required":
{"noise_sampler_type": (["gaussian", "uniform", "brownian"], ), {"noise_sampler_type": (get_noise_sampler_names(), ),
} }
} }
RETURN_TYPES = ("SAMPLER",) RETURN_TYPES = ("SAMPLER",)
@@ -146,14 +80,14 @@ class SamplerLCMCustom:
FUNCTION = "get_sampler" FUNCTION = "get_sampler"
def get_sampler(self, noise_sampler_type): def get_sampler(self, noise_sampler_type):
sampler = comfy.samplers.ksampler("lcm_custom_noise", {"noise_sampler": noise_sampler_type}) sampler = comfy.samplers.ksampler("lcm_custom_noise", {"noise_sampler_type": noise_sampler_type})
return (sampler, ) return (sampler, )
class SamplerCLYB_4M_SDE_MOMENTUMIZED: class SamplerCLYB_4M_SDE_MOMENTUMIZED:
@classmethod @classmethod
def INPUT_TYPES(s): def INPUT_TYPES(s):
return {"required": return {"required":
{"noise_sampler_type": (["gaussian", "uniform", "brownian", "highres-pyramid", "perlin", "laplacian"], ), {"noise_sampler_type": (get_noise_sampler_names(default="brownian"), ),
"momentum": ("FLOAT", {"default": 0.5, "min": -1.0, "max": 1.0, "step":0.01}), "momentum": ("FLOAT", {"default": 0.5, "min": -1.0, "max": 1.0, "step":0.01}),
"eta": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 100.0, "step":0.01}), "eta": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 100.0, "step":0.01}),
"s_noise": ("FLOAT", {"default": 1, "min": 0.0, "max": 100.0, "step":0.01}), "s_noise": ("FLOAT", {"default": 1, "min": 0.0, "max": 100.0, "step":0.01}),
@@ -165,14 +99,14 @@ class SamplerCLYB_4M_SDE_MOMENTUMIZED:
FUNCTION = "get_sampler" FUNCTION = "get_sampler"
def get_sampler(self, noise_sampler_type, eta, s_noise, momentum): def get_sampler(self, noise_sampler_type, eta, s_noise, momentum):
sampler = comfy.samplers.ksampler("clyb_4m_sde_momentumized", {"noise_sampler": noise_sampler_type, "eta": eta, "s_noise": s_noise, "momentum": momentum}) sampler = comfy.samplers.ksampler("clyb_4m_sde_momentumized", {"noise_sampler_type": noise_sampler_type, "eta": eta, "s_noise": s_noise, "momentum": momentum})
return (sampler, ) return (sampler, )
class SamplerEULER_ANCESTRAL_DANCING: class SamplerEULER_ANCESTRAL_DANCING:
@classmethod @classmethod
def INPUT_TYPES(s): def INPUT_TYPES(s):
return {"required": return {"required":
{"noise_sampler_type": (["gaussian", "uniform", "brownian", "highres-pyramid", "perlin", "laplacian"], ), {"noise_sampler_type": (get_noise_sampler_names(), ),
"eta": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 100.0, "step":0.01}), "eta": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 100.0, "step":0.01}),
"eta_dance": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 100.0, "step":0.01}), "eta_dance": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 100.0, "step":0.01}),
"s_noise": ("FLOAT", {"default": 1, "min": 0.0, "max": 100.0, "step":0.01}), "s_noise": ("FLOAT", {"default": 1, "min": 0.0, "max": 100.0, "step":0.01}),
@@ -185,14 +119,14 @@ class SamplerEULER_ANCESTRAL_DANCING:
FUNCTION = "get_sampler" FUNCTION = "get_sampler"
def get_sampler(self, noise_sampler_type, eta, s_noise, leap, eta_dance): def get_sampler(self, noise_sampler_type, eta, s_noise, leap, eta_dance):
sampler = comfy.samplers.ksampler("euler_ancestral_dancing", {"noise_sampler": noise_sampler_type, "eta": eta, "s_noise": s_noise, "leap": leap, "eta_dance": eta_dance}) sampler = comfy.samplers.ksampler("euler_ancestral_dancing", {"noise_sampler_type": noise_sampler_type, "eta": eta, "s_noise": s_noise, "leap": leap, "eta_dance": eta_dance})
return (sampler, ) return (sampler, )
class SamplerDPMPP_3M_SDE_DYN_ETA: class SamplerDPMPP_3M_SDE_DYN_ETA:
@classmethod @classmethod
def INPUT_TYPES(s): def INPUT_TYPES(s):
return {"required": return {"required":
{"noise_sampler_type": (["gaussian", "uniform", "brownian", "highres-pyramid", "perlin", "laplacian"], ), {"noise_sampler_type": (get_noise_sampler_names(default="brownian"), ),
"eta_max": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 100.0, "step":0.01}), "eta_max": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 100.0, "step":0.01}),
"eta_min": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 100.0, "step":0.01}), "eta_min": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 100.0, "step":0.01}),
"s_noise": ("FLOAT", {"default": 1, "min": 0.0, "max": 100.0, "step":0.01}), "s_noise": ("FLOAT", {"default": 1, "min": 0.0, "max": 100.0, "step":0.01}),
@@ -204,7 +138,7 @@ class SamplerDPMPP_3M_SDE_DYN_ETA:
FUNCTION = "get_sampler" FUNCTION = "get_sampler"
def get_sampler(self, noise_sampler_type, eta_max, eta_min, s_noise): def get_sampler(self, noise_sampler_type, eta_max, eta_min, s_noise):
sampler = comfy.samplers.ksampler("dpmpp_3m_sde_dynamic_eta", {"noise_sampler": noise_sampler_type, "eta_max": eta_max, "eta_min": eta_min, "s_noise": s_noise}) sampler = comfy.samplers.ksampler("dpmpp_3m_sde_dynamic_eta", {"noise_sampler_type": noise_sampler_type, "eta_max": eta_max, "eta_min": eta_min, "s_noise": s_noise})
return (sampler, ) return (sampler, )
### Schedulers ### Schedulers