mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-02-15 07:52:35 +08:00
Add KSamplerAdvancedTile noode.
This commit is contained in:
parent
777f6b1522
commit
19f520cb7b
161
nodes.py
161
nodes.py
@ -1332,6 +1332,164 @@ class KSamplerAdvanced:
|
|||||||
disable_noise = True
|
disable_noise = True
|
||||||
return common_ksampler(model, noise_seed, steps, cfg, sampler_name, scheduler, positive, negative, latent_image, denoise=denoise, disable_noise=disable_noise, start_step=start_at_step, last_step=end_at_step, force_full_denoise=force_full_denoise)
|
return common_ksampler(model, noise_seed, steps, cfg, sampler_name, scheduler, positive, negative, latent_image, denoise=denoise, disable_noise=disable_noise, start_step=start_at_step, last_step=end_at_step, force_full_denoise=force_full_denoise)
|
||||||
|
|
||||||
|
|
||||||
|
class KSamplerAdvancedTile:
|
||||||
|
@classmethod
|
||||||
|
def INPUT_TYPES(s):
|
||||||
|
return {
|
||||||
|
"required": {
|
||||||
|
"model": ("MODEL",),
|
||||||
|
"add_noise": (["enable", "disable"],),
|
||||||
|
"noise_seed": (
|
||||||
|
"INT",
|
||||||
|
{"default": 0, "min": 0, "max": 0xFFFFFFFFFFFFFFFF},
|
||||||
|
),
|
||||||
|
"tileX": (
|
||||||
|
"BOOLEAN",
|
||||||
|
{"default": False, "label_on": "enabled", "label_off": "disabled"},
|
||||||
|
),
|
||||||
|
"tileY": (
|
||||||
|
"BOOLEAN",
|
||||||
|
{"default": False, "label_on": "enabled", "label_off": "disabled"},
|
||||||
|
),
|
||||||
|
"steps": ("INT", {"default": 20, "min": 1, "max": 10000}),
|
||||||
|
"cfg": (
|
||||||
|
"FLOAT",
|
||||||
|
{
|
||||||
|
"default": 8.0,
|
||||||
|
"min": 0.0,
|
||||||
|
"max": 100.0,
|
||||||
|
"step": 0.1,
|
||||||
|
"round": 0.01,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
"sampler_name": (comfy.samplers.KSampler.SAMPLERS,),
|
||||||
|
"scheduler": (comfy.samplers.KSampler.SCHEDULERS,),
|
||||||
|
"positive": ("CONDITIONING",),
|
||||||
|
"negative": ("CONDITIONING",),
|
||||||
|
"latent_image": ("LATENT",),
|
||||||
|
"start_at_step": ("INT", {"default": 0, "min": 0, "max": 10000}),
|
||||||
|
"end_at_step": ("INT", {"default": 10000, "min": 0, "max": 10000}),
|
||||||
|
"return_with_leftover_noise": (["disable", "enable"],),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_TYPES = ("LATENT",)
|
||||||
|
FUNCTION = "sample"
|
||||||
|
CATEGORY = "Sampling/Tiled"
|
||||||
|
|
||||||
|
def set_layer_padding(self, layer, tileX, tileY):
|
||||||
|
"""Set padding mode and values for a convolutional layer based on tiling parameters."""
|
||||||
|
layer.padding_modeX = "circular" if tileX else "constant"
|
||||||
|
layer.padding_modeY = "circular" if tileY else "constant"
|
||||||
|
layer.paddingX = (
|
||||||
|
layer._reversed_padding_repeated_twice[0],
|
||||||
|
layer._reversed_padding_repeated_twice[1],
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
layer.paddingY = (
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
layer._reversed_padding_repeated_twice[2],
|
||||||
|
layer._reversed_padding_repeated_twice[3],
|
||||||
|
)
|
||||||
|
|
||||||
|
def apply_asymmetric_tiling(self, model, tileX, tileY):
|
||||||
|
"""Apply asymmetric tiling to all convolutional layers in the model."""
|
||||||
|
for layer in model.modules():
|
||||||
|
if isinstance(layer, torch.nn.Conv2d):
|
||||||
|
self.set_layer_padding(layer, tileX, tileY)
|
||||||
|
print(layer.paddingX, layer.paddingY)
|
||||||
|
|
||||||
|
def hijack_conv2d_methods(self, model, tileX: bool, tileY: bool):
|
||||||
|
"""Override the convolution methods of Conv2d layers in the model."""
|
||||||
|
for layer in model.modules():
|
||||||
|
if isinstance(layer, torch.nn.Conv2d):
|
||||||
|
self.set_layer_padding(layer, tileX, tileY)
|
||||||
|
|
||||||
|
def make_bound_method(method, current_layer):
|
||||||
|
def bound_method(self, *args, **kwargs):
|
||||||
|
return method(current_layer, *args, **kwargs)
|
||||||
|
|
||||||
|
return bound_method
|
||||||
|
|
||||||
|
bound_method = make_bound_method(self.replacement_conv2d_forward, layer)
|
||||||
|
layer._conv_forward = bound_method.__get__(layer, type(layer))
|
||||||
|
|
||||||
|
def replacement_conv2d_forward(self, layer, input: torch.Tensor, weight: torch.Tensor, bias: [torch.Tensor]):
|
||||||
|
"""Replacement method for convolutional forward pass."""
|
||||||
|
working = torch.nn.functional.pad(input, layer.paddingX, mode=layer.padding_modeX)
|
||||||
|
working = torch.nn.functional.pad(working, layer.paddingY, mode=layer.padding_modeY)
|
||||||
|
return torch.nn.functional.conv2d(working, weight, bias, layer.stride, (0, 0), layer.dilation, layer.groups)
|
||||||
|
|
||||||
|
def restore_conv2d_methods(self, model):
|
||||||
|
"""Restore the original convolution methods to Conv2d layers in the model."""
|
||||||
|
for layer in model.modules():
|
||||||
|
if isinstance(layer, torch.nn.Conv2d):
|
||||||
|
layer._conv_forward = torch.nn.Conv2d._conv_forward.__get__(layer, torch.nn.Conv2d)
|
||||||
|
|
||||||
|
def sample(
|
||||||
|
self,
|
||||||
|
model,
|
||||||
|
add_noise,
|
||||||
|
noise_seed,
|
||||||
|
tileX,
|
||||||
|
tileY,
|
||||||
|
steps,
|
||||||
|
cfg,
|
||||||
|
sampler_name,
|
||||||
|
scheduler,
|
||||||
|
positive,
|
||||||
|
negative,
|
||||||
|
latent_image,
|
||||||
|
start_at_step,
|
||||||
|
end_at_step,
|
||||||
|
return_with_leftover_noise,
|
||||||
|
denoise=1.0,
|
||||||
|
):
|
||||||
|
force_full_denoise = True
|
||||||
|
if return_with_leftover_noise == "enable":
|
||||||
|
force_full_denoise = False
|
||||||
|
disable_noise = False
|
||||||
|
if add_noise == "disable":
|
||||||
|
disable_noise = True
|
||||||
|
self.hijack_conv2d_methods(model.model, tileX == 1, tileY == 1)
|
||||||
|
result = common_ksampler(
|
||||||
|
model,
|
||||||
|
noise_seed,
|
||||||
|
steps,
|
||||||
|
cfg,
|
||||||
|
sampler_name,
|
||||||
|
scheduler,
|
||||||
|
positive,
|
||||||
|
negative,
|
||||||
|
latent_image,
|
||||||
|
denoise=denoise,
|
||||||
|
disable_noise=disable_noise,
|
||||||
|
start_step=start_at_step,
|
||||||
|
last_step=end_at_step,
|
||||||
|
force_full_denoise=force_full_denoise,
|
||||||
|
)
|
||||||
|
self.restore_conv2d_methods(model.model)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class CircularVAEDecode:
|
||||||
|
@classmethod
|
||||||
|
def INPUT_TYPES(s):
|
||||||
|
return {"required": {"samples": ("LATENT",), "vae": ("VAE",)}}
|
||||||
|
|
||||||
|
RETURN_TYPES = ("IMAGE",)
|
||||||
|
FUNCTION = "decode"
|
||||||
|
|
||||||
|
CATEGORY = "latent"
|
||||||
|
|
||||||
|
def decode(self, vae, samples):
|
||||||
|
for layer in [layer for layer in vae.first_stage_model.modules() if isinstance(layer, torch.nn.Conv2d)]:
|
||||||
|
layer.padding_mode = "circular"
|
||||||
|
return (vae.decode(samples["samples"]),)
|
||||||
|
|
||||||
class SaveImage:
|
class SaveImage:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.output_dir = folder_paths.get_output_directory()
|
self.output_dir = folder_paths.get_output_directory()
|
||||||
@ -1660,6 +1818,7 @@ NODE_CLASS_MAPPINGS = {
|
|||||||
"CLIPTextEncode": CLIPTextEncode,
|
"CLIPTextEncode": CLIPTextEncode,
|
||||||
"CLIPSetLastLayer": CLIPSetLastLayer,
|
"CLIPSetLastLayer": CLIPSetLastLayer,
|
||||||
"VAEDecode": VAEDecode,
|
"VAEDecode": VAEDecode,
|
||||||
|
"Circular VAEDecode": CircularVAEDecode,
|
||||||
"VAEEncode": VAEEncode,
|
"VAEEncode": VAEEncode,
|
||||||
"VAEEncodeForInpaint": VAEEncodeForInpaint,
|
"VAEEncodeForInpaint": VAEEncodeForInpaint,
|
||||||
"VAELoader": VAELoader,
|
"VAELoader": VAELoader,
|
||||||
@ -1685,6 +1844,7 @@ NODE_CLASS_MAPPINGS = {
|
|||||||
"ConditioningSetAreaPercentage": ConditioningSetAreaPercentage,
|
"ConditioningSetAreaPercentage": ConditioningSetAreaPercentage,
|
||||||
"ConditioningSetMask": ConditioningSetMask,
|
"ConditioningSetMask": ConditioningSetMask,
|
||||||
"KSamplerAdvanced": KSamplerAdvanced,
|
"KSamplerAdvanced": KSamplerAdvanced,
|
||||||
|
"KSamplerAdvancedTile": KSamplerAdvancedTile,
|
||||||
"SetLatentNoiseMask": SetLatentNoiseMask,
|
"SetLatentNoiseMask": SetLatentNoiseMask,
|
||||||
"LatentComposite": LatentComposite,
|
"LatentComposite": LatentComposite,
|
||||||
"LatentBlend": LatentBlend,
|
"LatentBlend": LatentBlend,
|
||||||
@ -1725,6 +1885,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
|||||||
# Sampling
|
# Sampling
|
||||||
"KSampler": "KSampler",
|
"KSampler": "KSampler",
|
||||||
"KSamplerAdvanced": "KSampler (Advanced)",
|
"KSamplerAdvanced": "KSampler (Advanced)",
|
||||||
|
"KSamplerAdvancedTile": "KSamplerTile (Advanced)",
|
||||||
# Loaders
|
# Loaders
|
||||||
"CheckpointLoader": "Load Checkpoint With Config (DEPRECATED)",
|
"CheckpointLoader": "Load Checkpoint With Config (DEPRECATED)",
|
||||||
"CheckpointLoaderSimple": "Load Checkpoint",
|
"CheckpointLoaderSimple": "Load Checkpoint",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user