mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-02-10 13:32:36 +08:00
Merge branch 'master' of github.com:comfyanonymous/ComfyUI
This commit is contained in:
commit
3a64e04a93
49
README.md
49
README.md
@ -448,29 +448,32 @@ The default installation includes a fast latent preview method that's low-resolu
|
|||||||
|
|
||||||
## Keyboard Shortcuts
|
## Keyboard Shortcuts
|
||||||
|
|
||||||
| Keybind | Explanation |
|
| Keybind | Explanation |
|
||||||
|---------------------------|--------------------------------------------------------------------------------------------------------------------|
|
|------------------------------------|--------------------------------------------------------------------------------------------------------------------|
|
||||||
| Ctrl + Enter | Queue up current graph for generation |
|
| Ctrl + Enter | Queue up current graph for generation |
|
||||||
| Ctrl + Shift + Enter | Queue up current graph as first for generation |
|
| Ctrl + Shift + Enter | Queue up current graph as first for generation |
|
||||||
| Ctrl + Z/Ctrl + Y | Undo/Redo |
|
| Ctrl + Z/Ctrl + Y | Undo/Redo |
|
||||||
| Ctrl + S | Save workflow |
|
| Ctrl + S | Save workflow |
|
||||||
| Ctrl + O | Load workflow |
|
| Ctrl + O | Load workflow |
|
||||||
| Ctrl + A | Select all nodes |
|
| Ctrl + A | Select all nodes |
|
||||||
| Alt + C | Collapse/uncollapse selected nodes |
|
| Alt + C | Collapse/uncollapse selected nodes |
|
||||||
| Ctrl + M | Mute/unmute selected nodes |
|
| Ctrl + M | Mute/unmute selected nodes |
|
||||||
| Ctrl + B | Bypass selected nodes (acts like the node was removed from the graph and the wires reconnected through) |
|
| Ctrl + B | Bypass selected nodes (acts like the node was removed from the graph and the wires reconnected through) |
|
||||||
| Delete/Backspace | Delete selected nodes |
|
| Delete/Backspace | Delete selected nodes |
|
||||||
| Ctrl + Delete/Backspace | Delete the current graph |
|
| Ctrl + Delete/Backspace | Delete the current graph |
|
||||||
| Space | Move the canvas around when held and moving the cursor |
|
| Space | Move the canvas around when held and moving the cursor |
|
||||||
| Ctrl/Shift + Click | Add clicked node to selection |
|
| Ctrl/Shift + Click | Add clicked node to selection |
|
||||||
| Ctrl + C/Ctrl + V | Copy and paste selected nodes (without maintaining connections to outputs of unselected nodes) |
|
| Ctrl + C/Ctrl + V | Copy and paste selected nodes (without maintaining connections to outputs of unselected nodes) |
|
||||||
| Ctrl + C/Ctrl + Shift + V | Copy and paste selected nodes (maintaining connections from outputs of unselected nodes to inputs of pasted nodes) |
|
| Ctrl + C/Ctrl + Shift + V | Copy and paste selected nodes (maintaining connections from outputs of unselected nodes to inputs of pasted nodes) |
|
||||||
| Shift + Drag | Move multiple selected nodes at the same time |
|
| Shift + Drag | Move multiple selected nodes at the same time |
|
||||||
| Ctrl + D | Load default graph |
|
| Ctrl + D | Load default graph |
|
||||||
| Q | Toggle visibility of the queue |
|
| Alt + `+` | Canvas Zoom in |
|
||||||
| H | Toggle visibility of history |
|
| Alt + `-` | Canvas Zoom out |
|
||||||
| R | Refresh graph |
|
| Ctrl + Shift + LMB + Vertical drag | Canvas Zoom in/out |
|
||||||
| Double-Click LMB | Open node quick search palette |
|
| Q | Toggle visibility of the queue |
|
||||||
|
| H | Toggle visibility of history |
|
||||||
|
| R | Refresh graph |
|
||||||
|
| Double-Click LMB | Open node quick search palette |
|
||||||
|
|
||||||
Ctrl can also be replaced with Cmd instead for macOS users
|
Ctrl can also be replaced with Cmd instead for macOS users
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
from PIL import Image, ImageFile, UnidentifiedImageError
|
||||||
|
|
||||||
def conditioning_set_values(conditioning, values={}):
|
def conditioning_set_values(conditioning, values={}):
|
||||||
c = []
|
c = []
|
||||||
@ -8,3 +9,17 @@ def conditioning_set_values(conditioning, values={}):
|
|||||||
c.append(n)
|
c.append(n)
|
||||||
|
|
||||||
return c
|
return c
|
||||||
|
|
||||||
|
def open_image(path):
|
||||||
|
prev_value = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
img = Image.open(path)
|
||||||
|
except (UnidentifiedImageError, ValueError): #PIL issues #4472 and #2445
|
||||||
|
prev_value = ImageFile.LOAD_TRUNCATED_IMAGES
|
||||||
|
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||||
|
img = Image.open(path)
|
||||||
|
finally:
|
||||||
|
if prev_value is not None:
|
||||||
|
ImageFile.LOAD_TRUNCATED_IMAGES = prev_value
|
||||||
|
return img
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import math
|
|||||||
import random
|
import random
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from PIL import Image, ImageOps, ImageSequence
|
from PIL import Image, ImageOps, ImageSequence, ImageFile
|
||||||
from PIL.PngImagePlugin import PngInfo
|
from PIL.PngImagePlugin import PngInfo
|
||||||
from natsort import natsorted
|
from natsort import natsorted
|
||||||
from pkg_resources import resource_filename
|
from pkg_resources import resource_filename
|
||||||
@ -1460,9 +1460,18 @@ class LoadImage:
|
|||||||
_, ext = os.path.splitext(image)
|
_, ext = os.path.splitext(image)
|
||||||
if ext == ".exr":
|
if ext == ".exr":
|
||||||
return load_exr(image_path, srgb=False)
|
return load_exr(image_path, srgb=False)
|
||||||
with open_image(image_path) as img:
|
with node_helpers.open_image(image_path)(image_path) as img:
|
||||||
for i in ImageSequence.Iterator(img):
|
for i in ImageSequence.Iterator(img):
|
||||||
|
prev_value = None
|
||||||
|
try:
|
||||||
i = ImageOps.exif_transpose(i)
|
i = ImageOps.exif_transpose(i)
|
||||||
|
except OSError:
|
||||||
|
prev_value = ImageFile.LOAD_TRUNCATED_IMAGES
|
||||||
|
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
||||||
|
i = ImageOps.exif_transpose(i)
|
||||||
|
finally:
|
||||||
|
if prev_value is not None:
|
||||||
|
ImageFile.LOAD_TRUNCATED_IMAGES = prev_value
|
||||||
if i.mode == 'I':
|
if i.mode == 'I':
|
||||||
i = i.point(lambda i: i * (1 / 255))
|
i = i.point(lambda i: i * (1 / 255))
|
||||||
image = i.convert("RGB")
|
image = i.convert("RGB")
|
||||||
|
|||||||
84
comfy/sd.py
84
comfy/sd.py
@ -14,7 +14,6 @@ from . import utils
|
|||||||
from . import clip_vision
|
from . import clip_vision
|
||||||
from . import gligen
|
from . import gligen
|
||||||
from . import diffusers_convert
|
from . import diffusers_convert
|
||||||
from . import model_base
|
|
||||||
from . import model_detection
|
from . import model_detection
|
||||||
|
|
||||||
from . import sd1_clip
|
from . import sd1_clip
|
||||||
@ -22,9 +21,9 @@ from . import sd2_clip
|
|||||||
from . import sdxl_clip
|
from . import sdxl_clip
|
||||||
|
|
||||||
from . import model_patcher
|
from . import model_patcher
|
||||||
|
from . import model_sampling
|
||||||
from . import lora
|
from . import lora
|
||||||
from .t2i_adapter import adapter
|
from .t2i_adapter import adapter
|
||||||
from . import supported_models_base
|
|
||||||
from .taesd import taesd
|
from .taesd import taesd
|
||||||
|
|
||||||
def load_model_weights(model, sd):
|
def load_model_weights(model, sd):
|
||||||
@ -418,6 +417,8 @@ def load_gligen(ckpt_path):
|
|||||||
return model_patcher.ModelPatcher(model, load_device=model_management.get_torch_device(), offload_device=model_management.unet_offload_device())
|
return model_patcher.ModelPatcher(model, load_device=model_management.get_torch_device(), offload_device=model_management.unet_offload_device())
|
||||||
|
|
||||||
def load_checkpoint(config_path=None, ckpt_path=None, output_vae=True, output_clip=True, embedding_directory=None, state_dict=None, config=None):
|
def load_checkpoint(config_path=None, ckpt_path=None, output_vae=True, output_clip=True, embedding_directory=None, state_dict=None, config=None):
|
||||||
|
logging.warning("Warning: The load checkpoint with config function is deprecated and will eventually be removed, please use the other one.")
|
||||||
|
model, clip, vae, _ = load_checkpoint_guess_config(ckpt_path, output_vae=output_vae, output_clip=output_clip, output_clipvision=False, embedding_directory=embedding_directory, output_model=True)
|
||||||
#TODO: this function is a mess and should be removed eventually
|
#TODO: this function is a mess and should be removed eventually
|
||||||
if config is None:
|
if config is None:
|
||||||
with open(config_path, 'r') as stream:
|
with open(config_path, 'r') as stream:
|
||||||
@ -425,81 +426,20 @@ def load_checkpoint(config_path=None, ckpt_path=None, output_vae=True, output_cl
|
|||||||
model_config_params = config['model']['params']
|
model_config_params = config['model']['params']
|
||||||
clip_config = model_config_params['cond_stage_config']
|
clip_config = model_config_params['cond_stage_config']
|
||||||
scale_factor = model_config_params['scale_factor']
|
scale_factor = model_config_params['scale_factor']
|
||||||
vae_config = model_config_params['first_stage_config']
|
|
||||||
|
|
||||||
fp16 = False
|
|
||||||
if "unet_config" in model_config_params:
|
|
||||||
if "params" in model_config_params["unet_config"]:
|
|
||||||
unet_config = model_config_params["unet_config"]["params"]
|
|
||||||
if "use_fp16" in unet_config:
|
|
||||||
fp16 = unet_config.pop("use_fp16")
|
|
||||||
if fp16:
|
|
||||||
unet_config["dtype"] = torch.float16
|
|
||||||
|
|
||||||
noise_aug_config = None
|
|
||||||
if "noise_aug_config" in model_config_params:
|
|
||||||
noise_aug_config = model_config_params["noise_aug_config"]
|
|
||||||
|
|
||||||
model_type = model_base.ModelType.EPS
|
|
||||||
|
|
||||||
if "parameterization" in model_config_params:
|
if "parameterization" in model_config_params:
|
||||||
if model_config_params["parameterization"] == "v":
|
if model_config_params["parameterization"] == "v":
|
||||||
model_type = model_base.ModelType.V_PREDICTION
|
m = model.clone()
|
||||||
|
class ModelSamplingAdvanced(model_sampling.ModelSamplingDiscrete, model_sampling.V_PREDICTION):
|
||||||
|
pass
|
||||||
|
m.add_object_patch("model_sampling", ModelSamplingAdvanced(model.model.model_config))
|
||||||
|
model = m
|
||||||
|
|
||||||
clip = None
|
layer_idx = clip_config.get("params", {}).get("layer_idx", None)
|
||||||
vae = None
|
if layer_idx is not None:
|
||||||
|
clip.clip_layer(layer_idx)
|
||||||
|
|
||||||
class WeightsLoader(torch.nn.Module):
|
return (model, clip, vae)
|
||||||
pass
|
|
||||||
|
|
||||||
if state_dict is None:
|
|
||||||
state_dict = utils.load_torch_file(ckpt_path)
|
|
||||||
|
|
||||||
class EmptyClass:
|
|
||||||
pass
|
|
||||||
|
|
||||||
model_config = supported_models_base.BASE({})
|
|
||||||
|
|
||||||
from . import latent_formats
|
|
||||||
model_config.latent_format = latent_formats.SD15(scale_factor=scale_factor)
|
|
||||||
model_config.unet_config = model_detection.convert_config(unet_config)
|
|
||||||
|
|
||||||
if config['model']["target"].endswith("ImageEmbeddingConditionedLatentDiffusion"):
|
|
||||||
model = model_base.SD21UNCLIP(model_config, noise_aug_config["params"], model_type=model_type)
|
|
||||||
else:
|
|
||||||
model = model_base.BaseModel(model_config, model_type=model_type)
|
|
||||||
|
|
||||||
if config['model']["target"].endswith("LatentInpaintDiffusion"):
|
|
||||||
model.set_inpaint()
|
|
||||||
|
|
||||||
if fp16:
|
|
||||||
model = model.half()
|
|
||||||
|
|
||||||
offload_device = model_management.unet_offload_device()
|
|
||||||
model = model.to(offload_device)
|
|
||||||
model.load_model_weights(state_dict, "model.diffusion_model.")
|
|
||||||
|
|
||||||
if output_vae:
|
|
||||||
vae_sd = utils.state_dict_prefix_replace(state_dict, {"first_stage_model.": ""}, filter_keys=True)
|
|
||||||
vae = VAE(sd=vae_sd, config=vae_config)
|
|
||||||
|
|
||||||
if output_clip:
|
|
||||||
w = WeightsLoader()
|
|
||||||
clip_target = EmptyClass()
|
|
||||||
clip_target.params = clip_config.get("params", {})
|
|
||||||
if clip_config["target"].endswith("FrozenOpenCLIPEmbedder"):
|
|
||||||
clip_target.clip = sd2_clip.SD2ClipModel
|
|
||||||
clip_target.tokenizer = sd2_clip.SD2Tokenizer
|
|
||||||
clip = CLIP(clip_target, embedding_directory=embedding_directory)
|
|
||||||
w.cond_stage_model = clip.cond_stage_model.clip_h
|
|
||||||
elif clip_config["target"].endswith("FrozenCLIPEmbedder"):
|
|
||||||
clip_target.clip = sd1_clip.SD1ClipModel
|
|
||||||
clip_target.tokenizer = sd1_clip.SD1Tokenizer
|
|
||||||
clip = CLIP(clip_target, embedding_directory=embedding_directory)
|
|
||||||
w.cond_stage_model = clip.cond_stage_model.clip_l
|
|
||||||
load_clip_weights(w, state_dict)
|
|
||||||
|
|
||||||
return (model_patcher.ModelPatcher(model, load_device=model_management.get_torch_device(), offload_device=offload_device), clip, vae)
|
|
||||||
|
|
||||||
def load_checkpoint_guess_config(ckpt_path, output_vae=True, output_clip=True, output_clipvision=False, embedding_directory=None, output_model=True):
|
def load_checkpoint_guess_config(ckpt_path, output_vae=True, output_clip=True, output_clipvision=False, embedding_directory=None, output_model=True):
|
||||||
sd = utils.load_torch_file(ckpt_path)
|
sd = utils.load_torch_file(ckpt_path)
|
||||||
|
|||||||
@ -164,6 +164,41 @@ class MaskEditorDialog extends ComfyDialog {
|
|||||||
return divElement;
|
return divElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createOpacitySlider(self, name, callback) {
|
||||||
|
const divElement = document.createElement('div');
|
||||||
|
divElement.id = "maskeditor-opacity-slider";
|
||||||
|
divElement.style.cssFloat = "left";
|
||||||
|
divElement.style.fontFamily = "sans-serif";
|
||||||
|
divElement.style.marginRight = "4px";
|
||||||
|
divElement.style.color = "var(--input-text)";
|
||||||
|
divElement.style.backgroundColor = "var(--comfy-input-bg)";
|
||||||
|
divElement.style.borderRadius = "8px";
|
||||||
|
divElement.style.borderColor = "var(--border-color)";
|
||||||
|
divElement.style.borderStyle = "solid";
|
||||||
|
divElement.style.fontSize = "15px";
|
||||||
|
divElement.style.height = "21px";
|
||||||
|
divElement.style.padding = "1px 6px";
|
||||||
|
divElement.style.display = "flex";
|
||||||
|
divElement.style.position = "relative";
|
||||||
|
divElement.style.top = "2px";
|
||||||
|
divElement.style.pointerEvents = "auto";
|
||||||
|
self.opacity_slider_input = document.createElement('input');
|
||||||
|
self.opacity_slider_input.setAttribute('type', 'range');
|
||||||
|
self.opacity_slider_input.setAttribute('min', '0.1');
|
||||||
|
self.opacity_slider_input.setAttribute('max', '1.0');
|
||||||
|
self.opacity_slider_input.setAttribute('step', '0.01')
|
||||||
|
self.opacity_slider_input.setAttribute('value', '0.7');
|
||||||
|
const labelElement = document.createElement("label");
|
||||||
|
labelElement.textContent = name;
|
||||||
|
|
||||||
|
divElement.appendChild(labelElement);
|
||||||
|
divElement.appendChild(self.opacity_slider_input);
|
||||||
|
|
||||||
|
self.opacity_slider_input.addEventListener("input", callback);
|
||||||
|
|
||||||
|
return divElement;
|
||||||
|
}
|
||||||
|
|
||||||
setlayout(imgCanvas, maskCanvas) {
|
setlayout(imgCanvas, maskCanvas) {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
@ -203,6 +238,13 @@ class MaskEditorDialog extends ComfyDialog {
|
|||||||
self.updateBrushPreview(self, null, null);
|
self.updateBrushPreview(self, null, null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.brush_opacity_slider = this.createOpacitySlider(self, "Opacity", (event) => {
|
||||||
|
self.brush_opacity = event.target.value;
|
||||||
|
if (self.brush_color_mode !== "negative") {
|
||||||
|
self.maskCanvas.style.opacity = self.brush_opacity;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.colorButton = this.createLeftButton(this.getColorButtonText(), () => {
|
this.colorButton = this.createLeftButton(this.getColorButtonText(), () => {
|
||||||
if (self.brush_color_mode === "black") {
|
if (self.brush_color_mode === "black") {
|
||||||
self.brush_color_mode = "white";
|
self.brush_color_mode = "white";
|
||||||
@ -237,6 +279,7 @@ class MaskEditorDialog extends ComfyDialog {
|
|||||||
bottom_panel.appendChild(this.saveButton);
|
bottom_panel.appendChild(this.saveButton);
|
||||||
bottom_panel.appendChild(cancelButton);
|
bottom_panel.appendChild(cancelButton);
|
||||||
bottom_panel.appendChild(this.brush_size_slider);
|
bottom_panel.appendChild(this.brush_size_slider);
|
||||||
|
bottom_panel.appendChild(this.brush_opacity_slider);
|
||||||
bottom_panel.appendChild(this.colorButton);
|
bottom_panel.appendChild(this.colorButton);
|
||||||
|
|
||||||
imgCanvas.style.position = "absolute";
|
imgCanvas.style.position = "absolute";
|
||||||
@ -472,7 +515,7 @@ class MaskEditorDialog extends ComfyDialog {
|
|||||||
else {
|
else {
|
||||||
return {
|
return {
|
||||||
mixBlendMode: "initial",
|
mixBlendMode: "initial",
|
||||||
opacity: "0.7",
|
opacity: this.brush_opacity,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -538,6 +581,7 @@ class MaskEditorDialog extends ComfyDialog {
|
|||||||
this.maskCtx.putImageData(maskData, 0, 0);
|
this.maskCtx.putImageData(maskData, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
brush_opacity = 0.7;
|
||||||
brush_size = 10;
|
brush_size = 10;
|
||||||
brush_color_mode = "black";
|
brush_color_mode = "black";
|
||||||
drawing_mode = false;
|
drawing_mode = false;
|
||||||
|
|||||||
@ -953,6 +953,12 @@ export class ComfyApp {
|
|||||||
|
|
||||||
const origProcessMouseDown = LGraphCanvas.prototype.processMouseDown;
|
const origProcessMouseDown = LGraphCanvas.prototype.processMouseDown;
|
||||||
LGraphCanvas.prototype.processMouseDown = function(e) {
|
LGraphCanvas.prototype.processMouseDown = function(e) {
|
||||||
|
// prepare for ctrl+shift drag: zoom start
|
||||||
|
if(e.ctrlKey && e.shiftKey && e.buttons) {
|
||||||
|
self.zoom_drag_start = [e.x, e.y, this.ds.scale];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const res = origProcessMouseDown.apply(this, arguments);
|
const res = origProcessMouseDown.apply(this, arguments);
|
||||||
|
|
||||||
this.selected_group_moving = false;
|
this.selected_group_moving = false;
|
||||||
@ -973,6 +979,26 @@ export class ComfyApp {
|
|||||||
|
|
||||||
const origProcessMouseMove = LGraphCanvas.prototype.processMouseMove;
|
const origProcessMouseMove = LGraphCanvas.prototype.processMouseMove;
|
||||||
LGraphCanvas.prototype.processMouseMove = function(e) {
|
LGraphCanvas.prototype.processMouseMove = function(e) {
|
||||||
|
// handle ctrl+shift drag
|
||||||
|
if(e.ctrlKey && e.shiftKey && self.zoom_drag_start) {
|
||||||
|
// stop canvas zoom action
|
||||||
|
if(!e.buttons) {
|
||||||
|
self.zoom_drag_start = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate delta
|
||||||
|
let deltaY = e.y - self.zoom_drag_start[1];
|
||||||
|
let startScale = self.zoom_drag_start[2];
|
||||||
|
|
||||||
|
let scale = startScale - deltaY/100;
|
||||||
|
|
||||||
|
this.ds.changeScale(scale, [this.ds.element.width/2, this.ds.element.height/2]);
|
||||||
|
this.graph.change();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const orig_selected_group = this.selected_group;
|
const orig_selected_group = this.selected_group;
|
||||||
|
|
||||||
if (this.selected_group && !this.selected_group_resizing && !this.selected_group_moving) {
|
if (this.selected_group && !this.selected_group_resizing && !this.selected_group_moving) {
|
||||||
@ -1059,6 +1085,20 @@ export class ComfyApp {
|
|||||||
// Trigger onPaste
|
// Trigger onPaste
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if((e.key === '+') && e.altKey) {
|
||||||
|
block_default = true;
|
||||||
|
let scale = this.ds.scale * 1.1;
|
||||||
|
this.ds.changeScale(scale, [this.ds.element.width/2, this.ds.element.height/2]);
|
||||||
|
this.graph.change();
|
||||||
|
}
|
||||||
|
|
||||||
|
if((e.key === '-') && e.altKey) {
|
||||||
|
block_default = true;
|
||||||
|
let scale = this.ds.scale * 1 / 1.1;
|
||||||
|
this.ds.changeScale(scale, [this.ds.element.width/2, this.ds.element.height/2]);
|
||||||
|
this.graph.change();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.graph.change();
|
this.graph.change();
|
||||||
|
|||||||
@ -141,6 +141,7 @@ class SplitSigmas:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
RETURN_TYPES = ("SIGMAS","SIGMAS")
|
RETURN_TYPES = ("SIGMAS","SIGMAS")
|
||||||
|
RETURN_NAMES = ("high_sigmas", "low_sigmas")
|
||||||
CATEGORY = "sampling/custom_sampling/sigmas"
|
CATEGORY = "sampling/custom_sampling/sigmas"
|
||||||
|
|
||||||
FUNCTION = "get_sigmas"
|
FUNCTION = "get_sigmas"
|
||||||
@ -150,6 +151,27 @@ class SplitSigmas:
|
|||||||
sigmas2 = sigmas[step:]
|
sigmas2 = sigmas[step:]
|
||||||
return (sigmas1, sigmas2)
|
return (sigmas1, sigmas2)
|
||||||
|
|
||||||
|
class SplitSigmasDenoise:
|
||||||
|
@classmethod
|
||||||
|
def INPUT_TYPES(s):
|
||||||
|
return {"required":
|
||||||
|
{"sigmas": ("SIGMAS", ),
|
||||||
|
"denoise": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RETURN_TYPES = ("SIGMAS","SIGMAS")
|
||||||
|
RETURN_NAMES = ("high_sigmas", "low_sigmas")
|
||||||
|
CATEGORY = "sampling/custom_sampling/sigmas"
|
||||||
|
|
||||||
|
FUNCTION = "get_sigmas"
|
||||||
|
|
||||||
|
def get_sigmas(self, sigmas, denoise):
|
||||||
|
steps = max(sigmas.shape[-1] - 1, 0)
|
||||||
|
total_steps = round(steps * denoise)
|
||||||
|
sigmas1 = sigmas[:-(total_steps)]
|
||||||
|
sigmas2 = sigmas[-(total_steps + 1):]
|
||||||
|
return (sigmas1, sigmas2)
|
||||||
|
|
||||||
class FlipSigmas:
|
class FlipSigmas:
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(s):
|
||||||
@ -623,6 +645,7 @@ NODE_CLASS_MAPPINGS = {
|
|||||||
"SamplerDPMPP_SDE": SamplerDPMPP_SDE,
|
"SamplerDPMPP_SDE": SamplerDPMPP_SDE,
|
||||||
"SamplerDPMAdaptative": SamplerDPMAdaptative,
|
"SamplerDPMAdaptative": SamplerDPMAdaptative,
|
||||||
"SplitSigmas": SplitSigmas,
|
"SplitSigmas": SplitSigmas,
|
||||||
|
"SplitSigmasDenoise": SplitSigmasDenoise,
|
||||||
"FlipSigmas": FlipSigmas,
|
"FlipSigmas": FlipSigmas,
|
||||||
|
|
||||||
"CFGGuider": CFGGuider,
|
"CFGGuider": CFGGuider,
|
||||||
|
|||||||
@ -20,8 +20,9 @@ class PatchModelAddDownscale:
|
|||||||
CATEGORY = "_for_testing"
|
CATEGORY = "_for_testing"
|
||||||
|
|
||||||
def patch(self, model, block_number, downscale_factor, start_percent, end_percent, downscale_after_skip, downscale_method, upscale_method):
|
def patch(self, model, block_number, downscale_factor, start_percent, end_percent, downscale_after_skip, downscale_method, upscale_method):
|
||||||
sigma_start = model.model.model_sampling.percent_to_sigma(start_percent)
|
model_sampling = model.get_model_object("model_sampling")
|
||||||
sigma_end = model.model.model_sampling.percent_to_sigma(end_percent)
|
sigma_start = model_sampling.percent_to_sigma(start_percent)
|
||||||
|
sigma_end = model_sampling.percent_to_sigma(end_percent)
|
||||||
|
|
||||||
def input_block_patch(h, transformer_options):
|
def input_block_patch(h, transformer_options):
|
||||||
if transformer_options["block"][1] == block_number:
|
if transformer_options["block"][1] == block_number:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user