Add BlehPlug and BlehDisableNoise.
Increase the range of upscale/downscale options in BlehDeepShrink.
This commit is contained in:
@@ -10,7 +10,7 @@ A ComfyUI nodes collection... eventually.
|
||||
4. Allow discarding penultimate sigma (look for the `BlehDiscardPenultimateSigma` node). This can be useful if you find certain samplers are ruining your image by spewing a bunch of noise into it at the very end (usually only an issue with `dpm2 a` or SDE samplers).
|
||||
5. Allow more conveniently switching between samplers during sampling (look for the [BlehInsaneChainSampler](#blehinsanechainsampler) node).
|
||||
6. Apply arbitrary model patches at an interval and/or for a percentage of sampling (look for the [BlehModelPatchConditional](#blehmodelpatchconditional) node).
|
||||
7. Ensure a seed is set even when `add_noise` is turned off in a sampler. Yes, that's right: if you don't have `add_noise` enabled _no_ seed gets set for samplers like `euler_a` and it's not possible to reproduce generations. (look for the [BlehForceSeedSampler](#blehforceseedsampler) node)
|
||||
7. Ensure a seed is set even when `add_noise` is turned off in a sampler. Yes, that's right: if you don't have `add_noise` enabled _no_ seed gets set for samplers like `euler_a` and it's not possible to reproduce generations. (look for the [BlehForceSeedSampler](#blehforceseedsampler) node). For `SamplerCustomAdvanced` you can use `BlehDisableNoise` to accomplish the same thing.
|
||||
8. Allows swapping to a refiner model at a predefined time (look for the [BlehRefinerAfter](#blehrefinerafter) node).
|
||||
9. Allow defining arbitrary model patches (look for the [BlehBlockOps](#blehblockops) node).
|
||||
|
||||
@@ -102,6 +102,14 @@ This is basically the same as chaining a bunch of samplers together and manually
|
||||
|
||||
Currently, the way ComfyUI's advanced and custom samplers work is if you turn off `add_noise` _no_ global RNG seed gets set. Samplers like `euler_a` use this (SDE samplers use a different RNG method and aren't subject to this issue). Anyway, the upshot is you will get a different generation every time regardless of what the seed is set to. This node simply wraps another sampler and ensures that the seed gets set.
|
||||
|
||||
### BlehDisableNoise
|
||||
|
||||
Basically the same idea as `BlehForceSeedSampler`, however it is usable with `SamplerCustomAdvanced`.
|
||||
|
||||
|
||||
### BlehPlug
|
||||
|
||||
You can connect this node to any input and it will be the same as if the input had no connection. Why is this useful? It's mainly for [Use Everywhere](https://github.com/chrisgoringe/cg-use-everywhere) — sometimes it's desirable to leave an input unconnected, but if you have Use Everywhere broadcasting an output it can be inconvenient. Just shove a plug in those inputs.
|
||||
|
||||
### BlehRefinerAfter
|
||||
|
||||
|
||||
+4
-2
@@ -8,17 +8,19 @@ if settings.SETTINGS.btp_enabled:
|
||||
from .py.nodes import (
|
||||
deepShrink,
|
||||
hyperTile,
|
||||
misc,
|
||||
modelPatchConditional,
|
||||
ops,
|
||||
refinerAfter,
|
||||
samplers,
|
||||
sigmas,
|
||||
)
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"BlehBlockOps": ops.BlehBlockOps,
|
||||
"BlehDeepShrink": deepShrink.DeepShrinkBleh,
|
||||
"BlehDiscardPenultimateSigma": sigmas.DiscardPenultimateSigma,
|
||||
"BlehDiscardPenultimateSigma": misc.DiscardPenultimateSigma,
|
||||
"BlehDisableNoise": misc.BlehDisableNoise,
|
||||
"BlehPlug": misc.BlehPlug,
|
||||
"BlehForceSeedSampler": samplers.BlehForceSeedSampler,
|
||||
"BlehHyperTile": hyperTile.HyperTileBleh,
|
||||
"BlehInsaneChainSampler": samplers.BlehInsaneChainSampler,
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
Note, only relatively significant changes to user-visible functionality will be included here. Most recent changes at the top.
|
||||
|
||||
## 20240423
|
||||
|
||||
* Added `BlehPlug` and `BlehDisableNoise` (see README for usage and description).
|
||||
* Increased the available upscale/downscale types for `BlehDeepShrink`.
|
||||
|
||||
## 20240412
|
||||
|
||||
* Added `BlehBlockOps` and `BlehLatentOps` nodes.
|
||||
|
||||
+11
-18
@@ -2,8 +2,7 @@
|
||||
|
||||
import bisect
|
||||
|
||||
import torch
|
||||
from comfy.utils import bislerp
|
||||
from .. import latent_utils # noqa: TID252
|
||||
|
||||
|
||||
class DeepShrinkBleh:
|
||||
@@ -47,8 +46,8 @@ class DeepShrinkBleh:
|
||||
{"default": 0.35, "min": 0.0, "max": 1.0, "step": 0.001},
|
||||
),
|
||||
"downscale_after_skip": ("BOOLEAN", {"default": True}),
|
||||
"downscale_method": (cls.upscale_methods,),
|
||||
"upscale_method": (cls.upscale_methods,),
|
||||
"downscale_method": (latent_utils.UPSCALE_METHODS,),
|
||||
"upscale_method": (latent_utils.UPSCALE_METHODS,),
|
||||
"antialias_downscale": ("BOOLEAN", {"default": False}),
|
||||
"antialias_upscale": ("BOOLEAN", {"default": False}),
|
||||
},
|
||||
@@ -135,29 +134,23 @@ class DeepShrinkBleh:
|
||||
)
|
||||
if scaled_scale >= 0.98 or width >= orig_width or height >= orig_height:
|
||||
return h
|
||||
if downscale_method == "bislerp":
|
||||
return bislerp(h, width, height)
|
||||
return torch.nn.functional.interpolate(
|
||||
return latent_utils.scale_samples(
|
||||
h,
|
||||
size=(height, width),
|
||||
width,
|
||||
height,
|
||||
mode=downscale_method,
|
||||
antialias=antialias_downscale,
|
||||
antialias_size=3 if antialias_downscale else 0,
|
||||
)
|
||||
|
||||
def output_block_patch(h, hsp, _transformer_options):
|
||||
if h.shape[2] == hsp.shape[2]:
|
||||
return h, hsp
|
||||
if upscale_method == "bislerp":
|
||||
return bislerp(
|
||||
h,
|
||||
hsp.shape[-1],
|
||||
hsp.shape[-2],
|
||||
), hsp
|
||||
return torch.nn.functional.interpolate(
|
||||
return latent_utils.scale_samples(
|
||||
h,
|
||||
size=(hsp.shape[-2], hsp.shape[-1]),
|
||||
hsp.shape[-1],
|
||||
hsp.shape[-2],
|
||||
mode=upscale_method,
|
||||
antialias=antialias_upscale,
|
||||
antialias_size=3 if antialias_upscale else 0,
|
||||
), hsp
|
||||
|
||||
m = model.clone()
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
import random
|
||||
|
||||
import torch
|
||||
|
||||
|
||||
class DiscardPenultimateSigma:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"enabled": ("BOOLEAN", {"default": True}),
|
||||
"sigmas": ("SIGMAS", {"forceInput": True}),
|
||||
},
|
||||
}
|
||||
|
||||
FUNCTION = "go"
|
||||
RETURN_TYPES = ("SIGMAS",)
|
||||
CATEGORY = "sampling/custom_sampling/sigmas"
|
||||
|
||||
def go(self, enabled, sigmas):
|
||||
if not enabled or len(sigmas) < 2:
|
||||
return (sigmas,)
|
||||
return (torch.cat((sigmas[:-2], sigmas[-1:])),)
|
||||
|
||||
|
||||
class SeededDisableNoise:
|
||||
def __init__(self, seed):
|
||||
self.seed = seed
|
||||
|
||||
def generate_noise(self, latent):
|
||||
samples = latent["samples"]
|
||||
torch.manual_seed(self.seed)
|
||||
random.seed(self.seed) # For good measure.
|
||||
return torch.zeros(
|
||||
samples.shape,
|
||||
dtype=samples.dtype,
|
||||
layout=samples.layout,
|
||||
device="cpu",
|
||||
)
|
||||
|
||||
|
||||
class BlehDisableNoise:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"noise_seed": (
|
||||
"INT",
|
||||
{"default": 0, "min": 0, "max": 0xFFFFFFFFFFFFFFFF},
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
def go(self, noise_seed):
|
||||
return (SeededDisableNoise(noise_seed),)
|
||||
|
||||
RETURN_TYPES = ("NOISE",)
|
||||
FUNCTION = "go"
|
||||
CATEGORY = "sampling/custom_sampling/noise"
|
||||
|
||||
|
||||
class Wildcard(str):
|
||||
__slots__ = ()
|
||||
|
||||
def __ne__(self, _unused):
|
||||
return False
|
||||
|
||||
|
||||
class BlehPlug:
|
||||
WILDCARD = Wildcard("*")
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {}
|
||||
|
||||
def go(self):
|
||||
return (None,)
|
||||
|
||||
RETURN_TYPES = (WILDCARD,)
|
||||
FUNCTION = "go"
|
||||
OUTPUT_NODE = False
|
||||
CATEGORY = "hacks"
|
||||
@@ -1,21 +0,0 @@
|
||||
import torch
|
||||
|
||||
|
||||
class DiscardPenultimateSigma:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"enabled": ("BOOLEAN", {"default": True}),
|
||||
"sigmas": ("SIGMAS", {"forceInput": True}),
|
||||
},
|
||||
}
|
||||
|
||||
FUNCTION = "go"
|
||||
RETURN_TYPES = ("SIGMAS",)
|
||||
CATEGORY = "sampling/custom_sampling/sigmas"
|
||||
|
||||
def go(self, enabled, sigmas):
|
||||
if not enabled or len(sigmas) < 2:
|
||||
return (sigmas,)
|
||||
return (torch.cat((sigmas[:-2], sigmas[-1:])),)
|
||||
Reference in New Issue
Block a user