Files
facok-ComfyUI-DiversityBoost/core_node.py
T
facok 4d6794e7c5 Release V3: polynomial frequency modulation + legacy node
Major rewrite of DiversityBoost core:

- Replace Butterworth LPF with polynomial frequency modulation
  (smooth continuous curve, token-grid normalized via DiT patch_size)
- Add hf_factor, lf_factor, transition parameters for fine control
- Add schedule parameter (flat/linear/cosine) for timestep decay
- Protect near-DC frequencies (r_norm < 1.0) from dc_preserve
  to prevent brightness/color shift
- Fix DC handling: step 1+ always preserves full DC
- Support 5D video latents

Rename Core node to V3 (node_id=DiversityBoostCoreV3).
Preserve old node as Legacy (node_id=DiversityBoostCore) for
backward compatibility.

Remove experimental DCW and Smart Patch nodes (superseded by V3).

Aggressive defaults tuned for strong diversity:
  strength=2.0, clamp=0.5, hf=1.0, lf=0.3, trans=2.0, sched=linear
2026-04-25 04:31:06 +08:00

90 lines
4.1 KiB
Python

"""DiversityBoost node — HF attenuation + DCT composition push."""
import time
from comfy_api.latest import io
from .core import build_diversity_fn
class DiversityBoostCoreV3(io.ComfyNode):
"""Restore composition diversity for distilled diffusion models.
Single post-cfg hook at step 0: first attenuates HF amplitude
(Butterworth LPF), then applies a random low-frequency DCT spatial
field to the blurred result. Push runs AFTER cleanup so its signal
cannot be erased by downstream processing.
"""
@classmethod
def define_schema(cls) -> io.Schema:
return io.Schema(
node_id="DiversityBoostCoreV3",
display_name="Diversity Boost (V3)",
category="sampling",
description="Restore composition diversity for distilled models. "
"HF attenuation + DCT composition push at step 0.",
inputs=[
io.Model.Input("model"),
io.Float.Input("strength", default=2.0, min=0.0, max=2.0, step=0.05,
tooltip="Composition push amplitude. "
"0 = cleanup only. 1.0 = moderate. 2.0 = strong."),
io.Float.Input("clamp", default=0.5, min=0.1, max=3.0, step=0.1,
tooltip="Safety clamp for DCT field values."),
io.Combo.Input("noise_type",
options=["pink", "white", "blue"],
default="pink",
tooltip="Frequency spectrum of random DCT coefficients. "
"pink = stronger composition push (recommended)."),
io.Float.Input("dc_preserve", default=0.0, min=0.0, max=1.0, step=0.1,
tooltip="DC amplitude preservation (1.0 = keep, 0.0 = zero). "
"Only affects step 0; step 1+ always preserves full DC."),
io.Boolean.Input("energy_compensate", default=False,
tooltip="Rescale output energy to match original."),
io.Float.Input("hf_factor", default=1.0, min=0.0, max=1.0, step=0.05,
tooltip="High-frequency attenuation [0, 1]. "
"1.0 = full attenuation. Only used in polynomial mode."),
io.Float.Input("lf_factor", default=0.3, min=0.0, max=1.0, step=0.05,
tooltip="Low-frequency amplification [0, 1]. "
"1.0 = +50% boost. Only used in polynomial mode."),
io.Float.Input("transition", default=2.0, min=0.5, max=4.0, step=0.1,
tooltip="Polynomial transition shape. "
"0.5 = steep, 1.0 = linear, 2.0 = smooth, 4.0 = very smooth."),
io.Combo.Input("schedule",
options=["flat", "linear", "cosine"],
default="linear",
tooltip="Timestep schedule. "
"flat = step 0 only. linear/cosine = progressive decay."),
],
outputs=[
io.Model.Output(display_name="model"),
],
)
@classmethod
def fingerprint_inputs(cls, **kwargs):
return time.time()
@classmethod
def execute(cls, model, strength, clamp, noise_type,
dc_preserve, energy_compensate,
hf_factor, lf_factor, transition, schedule) -> io.NodeOutput:
m = model.clone()
m.set_model_sampler_post_cfg_function(
build_diversity_fn(
strength=strength,
clamp_val=clamp,
noise_type=noise_type,
dc_preserve=dc_preserve,
energy_compensate=energy_compensate,
mode="polynomial",
hf_factor=hf_factor,
lf_factor=lf_factor,
transition=transition,
schedule=schedule,
),
)
return io.NodeOutput(m)