From f09312b33a801641bfe96f55ea26cd286ff1f6fb Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Tue, 9 Apr 2024 11:05:50 +0900 Subject: [PATCH] fix: show proper warning message instead of crash https://github.com/ltdrdata/ComfyUI-Impact-Pack/issues/470#issuecomment-2043954600 --- modules/impact/config.py | 2 +- modules/impact/hooks.py | 9 ++- modules/thirdparty/noise_nodes.py | 122 +++++++++++++++--------------- 3 files changed, 71 insertions(+), 62 deletions(-) diff --git a/modules/impact/config.py b/modules/impact/config.py index e204b8a..71701fc 100644 --- a/modules/impact/config.py +++ b/modules/impact/config.py @@ -2,7 +2,7 @@ import configparser import os -version_code = [4, 87, 3] +version_code = [4, 87, 4] version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '') dependency_version = 20 diff --git a/modules/impact/hooks.py b/modules/impact/hooks.py index 858c503..5cb3579 100644 --- a/modules/impact/hooks.py +++ b/modules/impact/hooks.py @@ -300,7 +300,14 @@ class UnsamplerHook(PixelKSampleHook): def post_encode(self, samples): cur_step = self.cur_step - Unsampler = noise_nodes.Unsampler + try: + Unsampler = noise_nodes.Unsampler + except: + if 'BNK_Unsampler' not in nodes.NODE_CLASS_MAPPINGS: + print("[Impact Pack] ERROR: ComfyUI version is outdated and the BNK_Unsampler node is not installed, so this feature cannot be used.") + raise Exception("ERROR: ComfyUI version is outdated and the BNK_Unsampler node is not installed, so this feature cannot be used.") + + Unsampler = nodes.NODE_CLASS_MAPPINGS['BNK_Unsampler'] end_at_step = self.start_end_at_step + (self.end_end_at_step - self.start_end_at_step) * cur_step / self.total_step end_at_step = int(end_at_step) diff --git a/modules/thirdparty/noise_nodes.py b/modules/thirdparty/noise_nodes.py index c16f6bb..e0f09d0 100644 --- a/modules/thirdparty/noise_nodes.py +++ b/modules/thirdparty/noise_nodes.py @@ -4,81 +4,83 @@ import comfy import torch -from comfy import sampler_helpers +try: + from comfy import sampler_helpers + class Unsampler: + @classmethod + def INPUT_TYPES(s): + return {"required": + {"model": ("MODEL",), + "steps": ("INT", {"default": 20, "min": 1, "max": 10000}), + "end_at_step": ("INT", {"default": 0, "min": 0, "max": 10000}), + "cfg": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 100.0}), + "sampler_name": (comfy.samplers.KSampler.SAMPLERS,), + "scheduler": (comfy.samplers.KSampler.SCHEDULERS,), + "normalize": (["disable", "enable"],), + "positive": ("CONDITIONING",), + "negative": ("CONDITIONING",), + "latent_image": ("LATENT",), + }} -class Unsampler: - @classmethod - def INPUT_TYPES(s): - return {"required": - {"model": ("MODEL",), - "steps": ("INT", {"default": 20, "min": 1, "max": 10000}), - "end_at_step": ("INT", {"default": 0, "min": 0, "max": 10000}), - "cfg": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 100.0}), - "sampler_name": (comfy.samplers.KSampler.SAMPLERS,), - "scheduler": (comfy.samplers.KSampler.SCHEDULERS,), - "normalize": (["disable", "enable"],), - "positive": ("CONDITIONING",), - "negative": ("CONDITIONING",), - "latent_image": ("LATENT",), - }} + RETURN_TYPES = ("LATENT",) + FUNCTION = "unsampler" - RETURN_TYPES = ("LATENT",) - FUNCTION = "unsampler" + CATEGORY = "sampling" - CATEGORY = "sampling" + def unsampler(self, model, cfg, sampler_name, steps, end_at_step, scheduler, normalize, positive, negative, + latent_image): + normalize = normalize == "enable" + device = comfy.model_management.get_torch_device() + latent = latent_image + latent_image = latent["samples"] - def unsampler(self, model, cfg, sampler_name, steps, end_at_step, scheduler, normalize, positive, negative, - latent_image): - normalize = normalize == "enable" - device = comfy.model_management.get_torch_device() - latent = latent_image - latent_image = latent["samples"] + end_at_step = min(end_at_step, steps - 1) + end_at_step = steps - end_at_step - end_at_step = min(end_at_step, steps - 1) - end_at_step = steps - end_at_step + noise = torch.zeros(latent_image.size(), dtype=latent_image.dtype, layout=latent_image.layout, device="cpu") + noise_mask = None + if "noise_mask" in latent: + noise_mask = comfy.sampler_helpers.prepare_mask(latent["noise_mask"], noise.shape, device) - noise = torch.zeros(latent_image.size(), dtype=latent_image.dtype, layout=latent_image.layout, device="cpu") - noise_mask = None - if "noise_mask" in latent: - noise_mask = comfy.sampler_helpers.prepare_mask(latent["noise_mask"], noise.shape, device) + noise = noise.to(device) + latent_image = latent_image.to(device) - noise = noise.to(device) - latent_image = latent_image.to(device) + conds0 = \ + {"positive": comfy.sampler_helpers.convert_cond(positive), + "negative": comfy.sampler_helpers.convert_cond(negative)} - conds0 = \ - {"positive": comfy.sampler_helpers.convert_cond(positive), - "negative": comfy.sampler_helpers.convert_cond(negative)} + conds = {} + for k in conds0: + conds[k] = list(map(lambda a: a.copy(), conds0[k])) - conds = {} - for k in conds0: - conds[k] = list(map(lambda a: a.copy(), conds0[k])) + models, inference_memory = comfy.sampler_helpers.get_additional_models(conds, model.model_dtype()) - models, inference_memory = comfy.sampler_helpers.get_additional_models(conds, model.model_dtype()) + comfy.model_management.load_models_gpu([model] + models, model.memory_required(noise.shape) + inference_memory) - comfy.model_management.load_models_gpu([model] + models, model.memory_required(noise.shape) + inference_memory) + sampler = comfy.samplers.KSampler(model, steps=steps, device=device, sampler=sampler_name, + scheduler=scheduler, denoise=1.0, model_options=model.model_options) - sampler = comfy.samplers.KSampler(model, steps=steps, device=device, sampler=sampler_name, - scheduler=scheduler, denoise=1.0, model_options=model.model_options) + sigmas = sampler.sigmas.flip(0) + 0.0001 - sigmas = sampler.sigmas.flip(0) + 0.0001 + pbar = comfy.utils.ProgressBar(steps) - pbar = comfy.utils.ProgressBar(steps) + def callback(step, x0, x, total_steps): + pbar.update_absolute(step + 1, total_steps) - def callback(step, x0, x, total_steps): - pbar.update_absolute(step + 1, total_steps) + samples = sampler.sample(noise, positive, negative, cfg=cfg, latent_image=latent_image, + force_full_denoise=False, denoise_mask=noise_mask, sigmas=sigmas, start_step=0, + last_step=end_at_step, callback=callback) + if normalize: + # technically doesn't normalize because unsampling is not guaranteed to end at a std given by the schedule + samples -= samples.mean() + samples /= samples.std() + samples = samples.cpu() - samples = sampler.sample(noise, positive, negative, cfg=cfg, latent_image=latent_image, - force_full_denoise=False, denoise_mask=noise_mask, sigmas=sigmas, start_step=0, - last_step=end_at_step, callback=callback) - if normalize: - # technically doesn't normalize because unsampling is not guaranteed to end at a std given by the schedule - samples -= samples.mean() - samples /= samples.std() - samples = samples.cpu() + comfy.sampler_helpers.cleanup_additional_models(models) - comfy.sampler_helpers.cleanup_additional_models(models) - - out = latent.copy() - out["samples"] = samples - return (out,) + out = latent.copy() + out["samples"] = samples + return (out,) +except Exception: + print(f"[Impact Pack] WARN: ComfyUI is an outdated version. UnsamplerHook won't work properly.") \ No newline at end of file