feat: add DavchaSamplerCustomAdvanced2 and DavchaScheduledSampler with enhanced sampling logic and schema definitions

This commit is contained in:
David Chatel
2026-02-06 13:35:39 +01:00
parent dad7edf475
commit 31e8cff6dd
+103 -2
View File
@@ -14,7 +14,7 @@ from nodes import LoraLoader
import nodes
from comfy_api.latest import io
import latent_preview
from comfy.samplers import sampler_object
from comfy.samplers import sampler_object, KSAMPLER
from comfy_extras.nodes_custom_sampler import Noise_EmptyNoise
import json
import math
@@ -1344,9 +1344,108 @@ class DavchaSamplerCustomAdvanced(io.ComfyNode):
return io.NodeOutput(out, out_denoised)
sample = execute
class DavchaSamplerCustomAdvanced2(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="DavchaSamplerCustomAdvanced2",
category="sampling/custom_sampling",
inputs=[
io.Noise.Input("noise"),
io.Guider.Input("guider"),
io.String.Input("samplers", multiline=False, dynamic_prompts=False),
io.Sigmas.Input("sigmas"),
io.String.Input("splits", multiline=False, dynamic_prompts=False),
io.Latent.Input("latent_image"),
],
outputs=[
io.Latent.Output(display_name="output"),
io.Latent.Output(display_name="denoised_output"),
]
)
@classmethod
def execute(cls, noise, guider, samplers, sigmas, splits, latent_image) -> io.NodeOutput:
samplers_names = [s.strip() for s in samplers.split(',')]
splits_list = [int(s.strip()) for s in splits.split(',')]
splits_l = np.array([0] + splits_list + [len(sigmas)])
sigmas_l = [sigmas[start:end] for start, end in list(zip(splits_l, splits_l[1:]+1))]
latent = latent_image
latent_image = latent["samples"]
latent = latent.copy()
latent_image = comfy.sample.fix_empty_latent_channels(guider.model_patcher, latent_image, latent.get("downscale_ratio_spacial", None))
latent["samples"] = latent_image
noise_mask = None
if "noise_mask" in latent:
noise_mask = latent["noise_mask"]
x0_output = {}
sigmas_len = sum([len(s) - 1 for s in sigmas_l])
callback = latent_preview.prepare_callback(guider.model_patcher, sigmas_len, x0_output)
disable_pbar = not comfy.utils.PROGRESS_BAR_ENABLED
curr_noise = noise.generate_noise(latent)
for sampler_name, sigmas in zip(samplers_names, sigmas_l):
sampler = sampler_object(sampler_name)
samples = guider.sample(curr_noise, latent_image, sampler, sigmas, denoise_mask=noise_mask, callback=callback, disable_pbar=disable_pbar, seed=noise.seed)
latent_image = samples
curr_noise = Noise_EmptyNoise().generate_noise({'samples': latent_image})
samples = samples.to(comfy.model_management.intermediate_device())
out = latent.copy()
out.pop("downscale_ratio_spacial", None)
out["samples"] = samples
if "x0" in x0_output:
x0_out = guider.model_patcher.model.process_latent_out(x0_output["x0"].cpu())
if samples.is_nested:
latent_shapes = [x.shape for x in samples.unbind()]
x0_out = comfy.nested_tensor.NestedTensor(comfy.utils.unpack_latents(x0_out, latent_shapes))
out_denoised = latent.copy()
out_denoised["samples"] = x0_out
else:
out_denoised = out
return io.NodeOutput(out, out_denoised)
sample = execute
def sampler_function(model_k, noise, sigmas, extra_args=None, callback=None, disable=None, **extra_options):
samplers = extra_options.pop('samplers')
splits = extra_options.pop('splits')
splits_l = np.array([0] + splits + [len(sigmas)])
sigmas_l = [sigmas[start:end] for start, end in list(zip(splits_l, splits_l[1:]+1))]
for sampler, sigmas in zip(samplers, sigmas_l):
extras = dict(**extra_options, **sampler.extra_options)
noise = sampler.sampler_function(model_k, noise, sigmas, extra_args=extra_args, callback=callback, disable=disable, **extras)
return noise
class DavchaScheduledSampler(io.ComfyNode):
@classmethod
def define_schema(cls):
template = io.Autogrow.TemplatePrefix(input=io.Sampler.Input("sampler"), prefix="sampler", min=1, max=10)
return io.Schema(
node_id="DavchaScheduledSampler",
category="sampling/custom_sampling/samplers",
inputs=[
io.Autogrow.Input("autogrow", template=template),
io.String.Input("splits", multiline=False, dynamic_prompts=False),
],
outputs=[
io.Sampler.Output(),
]
)
@classmethod
def execute(cls, autogrow, splits) -> io.NodeOutput:
splits_list = [int(s.strip()) for s in splits.split(',')]
samplers = [v for k, v in sorted(autogrow.items())]
return io.NodeOutput(KSAMPLER(sampler_function, extra_options={'samplers': samplers, 'splits': splits_list}))
NODE_CLASS_MAPPINGS = {
'DavchaScheduledSampler': DavchaScheduledSampler,
'DavchaSamplerCustomAdvanced': DavchaSamplerCustomAdvanced,
'DavchaSamplerCustomAdvanced2': DavchaSamplerCustomAdvanced2,
'DavchaRescaleSigmas': DavchaRescaleSigmas,
'DavchaQwenImageEditLoraTagLoader': DavchaQwenImageEditLoraTagLoader,
'DavchaScheduledTextEncoderQwenImageEditPlus': DavchaScheduledTextEncoderQwenImageEditPlus,
@@ -1378,7 +1477,9 @@ NODE_CLASS_MAPPINGS = {
}
NODE_DISPLAY_NAME_MAPPINGS = {
'DavchaScheduledSampler': 'Scheduled Sampler',
'DavchaSamplerCustomAdvanced': 'Custom Sampler Advanced',
'DavchaSamplerCustomAdvanced2': 'Custom Sampler Advanced 2',
'DavchaRescaleSigmas': 'Rescale Sigmas',
'DavchaQwenImageEditLoraTagLoader': 'Qwen Image Edit Lora Tag Loader',
'DavchaScheduledTextEncoderQwenImageEditPlus': 'Scheduled Text Encoder Qwen Image Edit Plus',