diff --git a/README.en.md b/README.en.md index a816ee7..7510b53 100644 --- a/README.en.md +++ b/README.en.md @@ -35,14 +35,14 @@ **v1.1.6 (2024/4/26)** +- `easy preSamplingCustom` added **alignYourSteps** to **schedulder** widget +- `easy kSampler` & `easy fullkSampler` added **Preview&Choose** to **image_output** widget - Added `easy styleAlignedBatchAlign` - Credit of [style_aligned_comfy](https://github.com/brianfitzgerald/style_aligned_comfy) - Added `easy ckptNames` - Added `easy controlnetNames` - Added `easy imagesSplitimage` - Batch images split into single images - Added `easy imageCount` - Get Image Count - Added `easy textSwitch` - Text Switch -- `easy kSampler` & `easy fullkSampler` added **Preview&Choose** to **image_output** widget - **v1.1.5 (2024/4/24)** diff --git a/README.md b/README.md index 6087e5d..0729934 100644 --- a/README.md +++ b/README.md @@ -39,13 +39,14 @@ **v1.1.6 (2024/4/26)** +- `easy preSamplingCustom` schedulder 增加 **alignYourSteps** 选项 +- `easy kSampler` 和 `easy fullkSampler` 的 **image_output** 增加 **Preview&Choose**选项 - 增加 `easy styleAlignedBatchAlign` - 风格对齐 [style_aligned_comfy](https://github.com/brianfitzgerald/style_aligned_comfy) - 增加 `easy ckptNames` - 增加 `easy controlnetNames` - 增加 `easy imagesSplitimage` - 批次图像拆分单张 - 增加 `easy imageCount` - 图像数量 - 增加 `easy textSwitch` - 文字切换 -- `easy kSampler` 和 `easy fullkSampler` 的 **image_output** 增加 **Preview&Choose**选项 **v1.1.5** diff --git a/py/easyNodes.py b/py/easyNodes.py index 7669810..98ee8d6 100644 --- a/py/easyNodes.py +++ b/py/easyNodes.py @@ -3275,7 +3275,7 @@ class samplerSettingsNoiseIn: return (new_pipe,) # 预采样设置(自定义) -from comfy_extras.nodes_custom_sampler import BasicGuider, DualCFGGuider, CFGGuider, KSamplerSelect, DisableNoise, RandomNoise, BasicScheduler, KarrasScheduler, ExponentialScheduler, PolyexponentialScheduler, SDTurboScheduler, VPScheduler, FlipSigmas +import comfy_extras.nodes_custom_sampler as custom_samplers from tqdm import trange class samplerCustomSettings: @@ -3290,7 +3290,7 @@ class samplerCustomSettings: "cfg": ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0}), "cfg_negative": ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0}), "sampler_name": (comfy.samplers.KSampler.SAMPLERS + ['inversed_euler'],), - "scheduler": (comfy.samplers.KSampler.SCHEDULERS + ['karrasADV','exponentialADV','polyExponential', 'sdturbo', 'vp'],), + "scheduler": (comfy.samplers.KSampler.SCHEDULERS + ['karrasADV','exponentialADV','polyExponential', 'sdturbo', 'vp', 'alignYourSteps'],), "steps": ("INT", {"default": 20, "min": 1, "max": 10000}), "sigma_max": ("FLOAT", {"default": 14.614642, "min": 0.0, "max": 1000.0, "step": 0.01, "round": False}), "sigma_min": ("FLOAT", {"default": 0.0291675, "min": 0.0, "max": 1000.0, "step": 0.01, "round": False}), @@ -3380,6 +3380,14 @@ class samplerCustomSettings: ksampler = comfy.samplers.KSAMPLER(sample_inversed_euler) return (ksampler,) + def get_custom_cls(self, sampler_name): + try: + cls = custom_samplers.__dict__[sampler_name] + print(cls) + return cls() + except: + raise Exception(f"Custom sampler {sampler_name} not found, Please updated your ComfyUI") + def settings(self, pipe, guider, cfg, cfg_negative, sampler_name, scheduler, steps, sigma_max, sigma_min, rho, beta_d, beta_min, eps_s, flip_sigmas, denoise, add_noise, seed, image_to_latent=None, latent=None, optional_sampler=None, optional_sigmas=None, prompt=None, extra_pnginfo=None, my_unique_id=None): # 图生图转换 @@ -3389,7 +3397,6 @@ class samplerCustomSettings: negative = pipe['negative'] batch_size = pipe["loader_settings"]["batch_size"] if "batch_size" in pipe["loader_settings"] else 1 _guider, sigmas = None, None - print(get_sd_version(model)) if image_to_latent is not None: if guider == "IP2P+DualCFG": positive, negative, latent = self.ip2p(pipe['positive'], pipe['negative'], vae, image_to_latent) @@ -3411,11 +3418,11 @@ class samplerCustomSettings: # guider if guider == 'CFG': - _guider, = CFGGuider().get_guider(model, positive, negative, cfg) + _guider, = self.get_custom_cls('CFGGuider').get_guider(model, positive, negative, cfg) elif guider in ['DualCFG', 'IP2P+DualCFG']: - _guider, = DualCFGGuider().get_guider(model, positive, negative, pipe['negative'], cfg, cfg_negative) + _guider, = self.get_custom_cls('DualCFGGuider').get_guider(model, positive, negative, pipe['negative'], cfg, cfg_negative) else: - _guider, = BasicGuider().get_guider(model, positive) + _guider, = self.get_custom_cls('BasicGuider').get_guider(model, positive) # sampler if optional_sampler: @@ -3424,35 +3431,42 @@ class samplerCustomSettings: if sampler_name == 'inversed_euler': sampler, = self.get_inversed_euler_sampler() else: - sampler, = KSamplerSelect().get_sampler(sampler_name) + sampler, = self.get_custom_cls('KSamplerSelect').get_sampler(sampler_name) # sigmas if optional_sigmas: sigmas = optional_sigmas else: if scheduler == 'vp': - sigmas, = VPScheduler().get_sigmas(steps, beta_d, beta_min, eps_s) + sigmas, = self.get_custom_cls('VPScheduler').get_sigmas(steps, beta_d, beta_min, eps_s) elif scheduler == 'karrasADV': - sigmas, = KarrasScheduler().get_sigmas(steps, sigma_max, sigma_min, rho) + sigmas, = self.get_custom_cls('KarrasScheduler').get_sigmas(steps, sigma_max, sigma_min, rho) elif scheduler == 'exponentialADV': - sigmas, = ExponentialScheduler().get_sigmas(steps, sigma_max, sigma_min) + sigmas, = self.get_custom_cls('ExponentialScheduler').get_sigmas(steps, sigma_max, sigma_min) elif scheduler == 'polyExponential': - sigmas, = PolyexponentialScheduler().get_sigmas(steps, sigma_max, sigma_min, rho) + sigmas, = self.get_custom_cls('PolyexponentialScheduler').get_sigmas(steps, sigma_max, sigma_min, rho) elif scheduler == 'sdturbo': - sigmas, = SDTurboScheduler().get_sigmas(model, steps, denoise) + sigmas, = self.get_custom_cls('SDTurboScheduler').get_sigmas(model, steps, denoise) elif scheduler == 'alignYourSteps': - pass + try: + from comfy_extras.nodes_align_your_steps import AlignYourStepsScheduler + model_type = get_sd_version(model) + if model_type == 'unknown': + raise Exception("This Model not supported") + sigmas, = AlignYourStepsScheduler().get_sigmas(model_type.upper(), steps) + except: + raise Exception("Please update your ComfyUI") else: - sigmas, = BasicScheduler().get_sigmas(model, scheduler, steps, denoise) + sigmas, = self.get_custom_cls('BasicScheduler').get_sigmas(model, scheduler, steps, denoise) # filp_sigmas if flip_sigmas: - sigmas, = FlipSigmas().get_sigmas(sigmas) + sigmas, = self.get_custom_cls('FlipSigmas').get_sigmas(sigmas) # noise if add_noise == 'disable': - noise, = DisableNoise().get_noise() + noise, = self.get_custom_cls('DisableNoise').get_noise() else: - noise, = RandomNoise().get_noise(seed) + noise, = self.get_custom_cls('RandomNoise').get_noise(seed) new_pipe = { "model": pipe['model'], diff --git a/py/layer_diffuse/func.py b/py/layer_diffuse/func.py index a4fbb24..e1c03e0 100644 --- a/py/layer_diffuse/func.py +++ b/py/layer_diffuse/func.py @@ -58,15 +58,15 @@ class LayerDiffuse: except: pass - if method in [LayerMethod.FG_ONLY_CONV, LayerMethod.FG_ONLY_ATTN] and sd_version == 'sd15': + if method in [LayerMethod.FG_ONLY_CONV, LayerMethod.FG_ONLY_ATTN] and sd_version == 'sd1': self.frames = 1 - elif method in [LayerMethod.BG_TO_BLEND, LayerMethod.FG_TO_BLEND, LayerMethod.BG_BLEND_TO_FG, LayerMethod.FG_BLEND_TO_BG] and sd_version == 'sd15': + elif method in [LayerMethod.BG_TO_BLEND, LayerMethod.FG_TO_BLEND, LayerMethod.BG_BLEND_TO_FG, LayerMethod.FG_BLEND_TO_BG] and sd_version == 'sd1': self.frames = 2 batch_size, _, height, width = samples['samples'].shape if batch_size % 2 != 0: raise Exception(f"The batch size should be a multiple of 2. 批次大小需为2的倍数") control_img = image - elif method == LayerMethod.EVERYTHING and sd_version == 'sd15': + elif method == LayerMethod.EVERYTHING and sd_version == 'sd1': batch_size, _, height, width = samples['samples'].shape self.frames = 3 if batch_size % 3 != 0: @@ -77,7 +77,7 @@ class LayerDiffuse: model_path = get_local_filepath(model_url, LAYER_DIFFUSION_DIR) layer_lora_state_dict = load_layer_model_state_dict(model_path) work_model = model.clone() - if sd_version == 'sd15': + if sd_version == 'sd1': patcher = AttentionSharingPatcher( work_model, self.frames, use_control=control_img is not None ) @@ -97,7 +97,7 @@ class LayerDiffuse: else: c_concat = model.model.latent_format.process_in(torch.cat([samples["samples"], blend_samples["samples"]], dim=1)) samp_model, positive, negative = (work_model,) + self.apply_layer_c_concat(positive, negative, c_concat) - elif sd_version == 'sd15': + elif sd_version == 'sd1': if method in [LayerMethod.BG_TO_BLEND, LayerMethod.BG_BLEND_TO_FG]: additional_cond = (additional_cond[0], None) elif method in [LayerMethod.FG_TO_BLEND, LayerMethod.FG_BLEND_TO_BG]: @@ -169,7 +169,7 @@ class LayerDiffuse: if sd_version not in ['sdxl', 'sd15']: raise Exception(f"Only SDXL and SD1.5 model supported for Layer Diffusion") method = self.get_layer_diffusion_method(layer_diffusion_method, blend_samples is not None) - sd15_allow = True if sd_version == 'sd15' and method in [LayerMethod.FG_ONLY_ATTN, LayerMethod.EVERYTHING, LayerMethod.BG_TO_BLEND, LayerMethod.BG_BLEND_TO_FG] else False + sd15_allow = True if sd_version == 'sd1' and method in [LayerMethod.FG_ONLY_ATTN, LayerMethod.EVERYTHING, LayerMethod.BG_TO_BLEND, LayerMethod.BG_BLEND_TO_FG] else False sdxl_allow = True if sd_version == 'sdxl' and method in [LayerMethod.FG_ONLY_CONV, LayerMethod.FG_ONLY_ATTN, LayerMethod.BG_BLEND_TO_FG] else False if sdxl_allow or sd15_allow: if self.vae_transparent_decoder is None: diff --git a/py/libs/utils.py b/py/libs/utils.py index 11f4fa5..0b33e27 100644 --- a/py/libs/utils.py +++ b/py/libs/utils.py @@ -98,13 +98,12 @@ import comfy.supported_models_base def get_sd_version(model): base: BaseModel = model.model model_config: comfy.supported_models.supported_models_base.BASE = base.model_config - print(model_config) if isinstance(model_config, comfy.supported_models.SDXL): return 'sdxl' elif isinstance( model_config, (comfy.supported_models.SD15, comfy.supported_models.SD20) ): - return 'sd15' + return 'sd1' elif isinstance( model_config, (comfy.supported_models.SVD_img2vid) ): diff --git a/web/js/easy/easyDynamicWidgets.js b/web/js/easy/easyDynamicWidgets.js index a82628a..7810ca3 100644 --- a/web/js/easy/easyDynamicWidgets.js +++ b/web/js/easy/easyDynamicWidgets.js @@ -297,7 +297,9 @@ function widgetLogic(node, widget) { toggleWidget(node, findWidgetByName(node, 'beta_min'),true) toggleWidget(node, findWidgetByName(node, 'eps_s'),true) }else{ - toggleWidget(node, findWidgetByName(node, 'denoise'),true) + if(widget.value == 'alignYourSteps'){ + toggleWidget(node, findWidgetByName(node, 'denoise')) + }else toggleWidget(node, findWidgetByName(node, 'denoise'),true) toggleWidget(node, findWidgetByName(node, 'sigma_max')) toggleWidget(node, findWidgetByName(node, 'sigma_min')) toggleWidget(node, findWidgetByName(node, 'beta_d'))