From ba9548f75637fbc091c87083b9fc361264ccc4e6 Mon Sep 17 00:00:00 2001 From: xufeng <57523724+lgldlk@users.noreply.github.com> Date: Sun, 29 Jun 2025 03:24:02 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E2=80=9C--whitelist-custom-nodes=E2=80=9D?= =?UTF-8?q?=20args=20for=20comfy=20core=20to=20go=20with=20=E2=80=9C--disa?= =?UTF-8?q?ble-all-custom-nodes=E2=80=9D=20for=20development=20purposes=20?= =?UTF-8?q?=20(#8592)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: “--whitelist-custom-nodes” args for comfy core to go with “--disable-all-custom-nodes” for development purposes * feat: Simplify custom nodes whitelist logic to use consistent code paths --- comfy/cli_args.py | 1 + main.py | 11 +++++++---- nodes.py | 3 +++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/comfy/cli_args.py b/comfy/cli_args.py index 741ecac3ff3..7234a7ba097 100644 --- a/comfy/cli_args.py +++ b/comfy/cli_args.py @@ -151,6 +151,7 @@ class PerformanceFeature(enum.Enum): parser.add_argument("--disable-metadata", action="store_true", help="Disable saving prompt metadata in files.") parser.add_argument("--disable-all-custom-nodes", action="store_true", help="Disable loading all custom nodes.") +parser.add_argument("--whitelist-custom-nodes", type=str, nargs='+', default=[], help="Specify custom node folders to load even when --disable-all-custom-nodes is enabled.") parser.add_argument("--disable-api-nodes", action="store_true", help="Disable loading all api nodes.") parser.add_argument("--multi-user", action="store_true", help="Enables per-user storage.") diff --git a/main.py b/main.py index 0d7c97dcb56..5dd3c92d27f 100644 --- a/main.py +++ b/main.py @@ -66,9 +66,6 @@ def execute_script(script_path): logging.error(f"Failed to execute startup-script: {script_path} / {e}") return False - if args.disable_all_custom_nodes: - return - node_paths = folder_paths.get_folder_paths("custom_nodes") for custom_node_path in node_paths: possible_modules = os.listdir(custom_node_path) @@ -81,6 +78,9 @@ def execute_script(script_path): script_path = os.path.join(module_path, "prestartup_script.py") if os.path.exists(script_path): + if args.disable_all_custom_nodes and possible_module not in args.whitelist_custom_nodes: + logging.info(f"Prestartup Skipping {possible_module} due to disable_all_custom_nodes and whitelist_custom_nodes") + continue time_before = time.perf_counter() success = execute_script(script_path) node_prestartup_times.append((time.perf_counter() - time_before, module_path, success)) @@ -276,7 +276,10 @@ def start_comfyui(asyncio_loop=None): prompt_server = server.PromptServer(asyncio_loop) hook_breaker_ac10a0.save_functions() - nodes.init_extra_nodes(init_custom_nodes=not args.disable_all_custom_nodes, init_api_nodes=not args.disable_api_nodes) + nodes.init_extra_nodes( + init_custom_nodes=True, + init_api_nodes=not args.disable_api_nodes + ) hook_breaker_ac10a0.restore_functions() cuda_malloc_warning() diff --git a/nodes.py b/nodes.py index 11aa50fcee9..99411a1fe1b 100644 --- a/nodes.py +++ b/nodes.py @@ -2187,6 +2187,9 @@ def init_external_custom_nodes(): module_path = os.path.join(custom_node_path, possible_module) if os.path.isfile(module_path) and os.path.splitext(module_path)[1] != ".py": continue if module_path.endswith(".disabled"): continue + if args.disable_all_custom_nodes and possible_module not in args.whitelist_custom_nodes: + logging.info(f"Skipping {possible_module} due to disable_all_custom_nodes and whitelist_custom_nodes") + continue time_before = time.perf_counter() success = load_custom_node(module_path, base_node_names, module_parent="custom_nodes") node_import_times.append((time.perf_counter() - time_before, module_path, success)) From a3cf272522f9820c3f379aa821729404cb4cf821 Mon Sep 17 00:00:00 2001 From: comfyanonymous <121283862+comfyanonymous@users.noreply.github.com> Date: Sat, 28 Jun 2025 12:53:40 -0700 Subject: [PATCH 2/4] Skip custom node logic completely if disabled and no whitelisted nodes. (#8719) --- main.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 5dd3c92d27f..d488c0f4c12 100644 --- a/main.py +++ b/main.py @@ -55,6 +55,9 @@ def apply_custom_paths(): def execute_prestartup_script(): + if args.disable_all_custom_nodes and len(args.whitelist_custom_nodes) == 0: + return + def execute_script(script_path): module_name = os.path.splitext(script_path)[0] try: @@ -277,7 +280,7 @@ def start_comfyui(asyncio_loop=None): hook_breaker_ac10a0.save_functions() nodes.init_extra_nodes( - init_custom_nodes=True, + init_custom_nodes=(not args.disable_all_custom_nodes) or len(args.whitelist_custom_nodes) > 0, init_api_nodes=not args.disable_api_nodes ) hook_breaker_ac10a0.restore_functions() From 396454fa410781008015c73f7e0a5014dac0609e Mon Sep 17 00:00:00 2001 From: comfyanonymous <121283862+comfyanonymous@users.noreply.github.com> Date: Sat, 28 Jun 2025 15:12:56 -0700 Subject: [PATCH 3/4] Reorder the schedulers so simple is the default one. (#8722) --- comfy/samplers.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/comfy/samplers.py b/comfy/samplers.py index efe9bf8670c..078a675f45b 100644 --- a/comfy/samplers.py +++ b/comfy/samplers.py @@ -1039,13 +1039,13 @@ class SchedulerHandler(NamedTuple): use_ms: bool = True SCHEDULER_HANDLERS = { - "normal": SchedulerHandler(normal_scheduler), + "simple": SchedulerHandler(simple_scheduler), + "sgm_uniform": SchedulerHandler(partial(normal_scheduler, sgm=True)), "karras": SchedulerHandler(k_diffusion_sampling.get_sigmas_karras, use_ms=False), "exponential": SchedulerHandler(k_diffusion_sampling.get_sigmas_exponential, use_ms=False), - "sgm_uniform": SchedulerHandler(partial(normal_scheduler, sgm=True)), - "simple": SchedulerHandler(simple_scheduler), "ddim_uniform": SchedulerHandler(ddim_scheduler), "beta": SchedulerHandler(beta_scheduler), + "normal": SchedulerHandler(normal_scheduler), "linear_quadratic": SchedulerHandler(linear_quadratic_schedule), "kl_optimal": SchedulerHandler(kl_optimal_scheduler, use_ms=False), } From 5b4eb021cb392680c62ef5c2bc1afe560bde37b3 Mon Sep 17 00:00:00 2001 From: chaObserv <154517000+chaObserv@users.noreply.github.com> Date: Sun, 29 Jun 2025 06:13:13 +0800 Subject: [PATCH 4/4] Perpneg guider with updated pre and post-cfg (#8698) --- comfy_extras/nodes_perpneg.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/comfy_extras/nodes_perpneg.py b/comfy_extras/nodes_perpneg.py index 6c6f71767a3..f051cbf9a2b 100644 --- a/comfy_extras/nodes_perpneg.py +++ b/comfy_extras/nodes_perpneg.py @@ -69,8 +69,17 @@ def predict_noise(self, x, timestep, model_options={}, seed=None): negative_cond = self.conds.get("negative", None) empty_cond = self.conds.get("empty_negative_prompt", None) - (noise_pred_pos, noise_pred_neg, noise_pred_empty) = \ - comfy.samplers.calc_cond_batch(self.inner_model, [positive_cond, negative_cond, empty_cond], x, timestep, model_options) + conds = [positive_cond, negative_cond, empty_cond] + + out = comfy.samplers.calc_cond_batch(self.inner_model, conds, x, timestep, model_options) + + # Apply pre_cfg_functions since sampling_function() is skipped + for fn in model_options.get("sampler_pre_cfg_function", []): + args = {"conds":conds, "conds_out": out, "cond_scale": self.cfg, "timestep": timestep, + "input": x, "sigma": timestep, "model": self.inner_model, "model_options": model_options} + out = fn(args) + + noise_pred_pos, noise_pred_neg, noise_pred_empty = out cfg_result = perp_neg(x, noise_pred_pos, noise_pred_neg, noise_pred_empty, self.neg_scale, self.cfg) # normally this would be done in cfg_function, but we skipped @@ -82,6 +91,7 @@ def predict_noise(self, x, timestep, model_options={}, seed=None): "denoised": cfg_result, "cond": positive_cond, "uncond": negative_cond, + "cond_scale": self.cfg, "model": self.inner_model, "uncond_denoised": noise_pred_neg, "cond_denoised": noise_pred_pos,