diff --git a/README.en.md b/README.en.md index a57f1c5..a239faf 100644 --- a/README.en.md +++ b/README.en.md @@ -39,6 +39,12 @@ Usage:
## Changelog + +**2024-02-26** + +- Fixed the error of SDXLClipModel in ComfyUI revision 2016[c2cb8e88] and above (the revision number was judged to be compatible with the old revision) +- Fixed `easy detailerFix` generation error when batch size is greater than 1 + **v1.0.8(2024-02-25)** - `easy cascadeLoader` stage_c and stage_b support the checkpoint model (Download [checkpoints](https://huggingface.co/stabilityai/stable-cascade/tree/main/comfyui_checkpoints) models) diff --git a/README.md b/README.md index dfe5e06..408d265 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,11 @@ stage_c 与 stage_b 可以使用[checkpoints](https://huggingface.co/stabilityai ## 更新日志 +**2024-02-26** + +- 修复 SDXLClipModel 在 ComfyUI 修订版本号 2016[c2cb8e88] 及以上的报错(判断了版本号可兼容老版本) +- 修复 `easy detailerFix` 批次大小大于1时生成出错 + **v1.0.8(2024-02-25)** - `easy cascadeLoader` stage_c 与 stage_b 支持checkpoint模型 (需要下载[checkpoints](https://huggingface.co/stabilityai/stable-cascade/tree/main/comfyui_checkpoints)) @@ -59,7 +64,6 @@ stage_c 与 stage_b 可以使用[checkpoints](https://huggingface.co/stabilityai - 增加 `easy preSamplingCascade` - stabled cascade stage_c 预采样参数 - 增加 `easy fullCascadeKSampler` - stable cascade stage_c 完整版采样器 - 增加 `easy cascadeKSampler` - stable cascade stage-c ksampler simple -- 优化图生图流程[示例](https://github.com/yolain/ComfyUI-Easy-Use?tab=readme-ov-file#图生图) **v1.0.6 (2024-02-16)** diff --git a/py/adv_encode.py b/py/adv_encode.py index db90c8b..66f1c94 100644 --- a/py/adv_encode.py +++ b/py/adv_encode.py @@ -4,9 +4,9 @@ import itertools from comfy import model_management from comfy.sdxl_clip import SDXLClipModel, SDXLRefinerClipModel, SDXLClipG - from nodes import NODE_CLASS_MAPPINGS +from .libs.utils import compare_revision def _grouper(n, iterable): it = iter(iterable) @@ -243,7 +243,11 @@ def encode_token_weights_l(model, token_weight_pairs): def encode_token_weights(model, token_weight_pairs, encode_func): if model.layer_idx is not None: - model.cond_stage_model.clip_layer(model.layer_idx) + # 2016 [c2cb8e88] 及以上版本去除了sdxl clip的clip_layer方法 + if compare_revision(2016): + model.cond_stage_model.set_clip_options({'layer': model.layer_idx}) + else: + model.cond_stage_model.clip_layer(model.layer_idx) model_management.load_model_gpu(model.patcher) return encode_func(model.cond_stage_model, token_weight_pairs) diff --git a/py/easyNodes.py b/py/easyNodes.py index 5c63394..4bc4456 100644 --- a/py/easyNodes.py +++ b/py/easyNodes.py @@ -3182,16 +3182,10 @@ class preDetailerFix: if vae is None: raise Exception(f"[ERROR] pipe['vae'] is missing") if optional_image is not None: - batch_size = pipe["loader_settings"]["batch_size"] if "batch_size" in pipe["loader_settings"] else 1 - samples = {"samples": vae.encode(optional_image)} - samples = RepeatLatentBatch().repeat(samples, batch_size)[0] - image = optional_image + images = optional_image else: - samples = pipe["samples"] if "samples" in pipe else None - if samples is None: - raise Exception(f"[ERROR] pipe['samples'] is missing") - image = pipe["images"] if "images" in pipe else None - if image is None: + images = pipe["images"] if "images" in pipe else None + if images is None: raise Exception(f"[ERROR] pipe['image'] is missing") positive = pipe["positive"] if "positive" in pipe else None if positive is None: @@ -3209,8 +3203,7 @@ class preDetailerFix: loader_settings = pipe["loader_settings"] if "loader_settings" in pipe else {} new_pipe = { - "samples": samples, - "images": image, + "images": images, "model": model, "clip": clip, "vae": vae, @@ -3325,21 +3318,22 @@ class detailerFix: start_time = int(time.time() * 1000) cls = ALL_NODE_CLASS_MAPPINGS["FaceDetailer"] - enhanced_img, cropped_enhanced, cropped_enhanced_alpha, mask, cnet_pil_list = cls().enhance_face( + + result_img, result_cropped_enhanced, result_cropped_enhanced_alpha, result_mask, pipe, result_cnet_images = cls().doit( image, model, clip, vae, guide_size, guide_size_for, max_size, seed, steps, cfg, sampler_name, scheduler, positive, negative, denoise, feather, noise_mask, force_inpaint, bbox_threshold, bbox_dilation, bbox_crop_factor, sam_detection_hint, sam_dilation, sam_threshold, sam_bbox_expansion, sam_mask_hint_threshold, - sam_mask_hint_use_negative, drop_size, bbox_detector_opt, segm_detector_opt, sam_model_opt, wildcard, - detailer_hook=None, cycle=cycle) + sam_mask_hint_use_negative, drop_size, bbox_detector_opt, wildcard, cycle, sam_model_opt, segm_detector_opt, + detailer_hook=None) # 细节修复结束时间 end_time = int(time.time() * 1000) spent_time = '细节修复:' + str((end_time - start_time) / 1000) + '秒' - results = easySave(enhanced_img, save_prefix, image_output, prompt, extra_pnginfo) + results = easySave(result_img, save_prefix, image_output, prompt, extra_pnginfo) sampler.update_value_by_id("results", my_unique_id, results) # Clean loaded_objects @@ -3347,7 +3341,7 @@ class detailerFix: new_pipe = { "samples": None, - "images": enhanced_img, + "images": result_img, "model": model, "clip": clip, "vae": vae, @@ -3372,12 +3366,12 @@ class detailerFix: if image_output in ("Hide", "Hide/Save"): return {"ui": {}, - "result": (new_pipe, enhanced_img, cropped_enhanced, cropped_enhanced_alpha, mask, cnet_pil_list)} + "result": (new_pipe, result_img, result_cropped_enhanced, result_cropped_enhanced_alpha, result_mask, result_cnet_images )} if image_output in ("Sender", "Sender/Save"): PromptServer.instance.send_sync("img-send", {"link_id": link_id, "images": results}) - return {"ui": {"images": results}, "result": (new_pipe, enhanced_img, cropped_enhanced, cropped_enhanced_alpha, mask, cnet_pil_list)} + return {"ui": {"images": results}, "result": (new_pipe, result_img, result_cropped_enhanced, result_cropped_enhanced_alpha, result_mask, result_cnet_images )} def add_folder_path_and_extensions(folder_name, full_folder_paths, extensions): for full_folder_path in full_folder_paths: diff --git a/py/libs/utils.py b/py/libs/utils.py index 7cd2165..bb05a14 100644 --- a/py/libs/utils.py +++ b/py/libs/utils.py @@ -1,3 +1,20 @@ +comfy_ui_revision = None +def get_comfyui_revision(): + try: + import git + import os + import folder_paths + repo = git.Repo(os.path.dirname(folder_paths.__file__)) + comfy_ui_revision = len(list(repo.iter_commits('HEAD'))) + except: + comfy_ui_revision = "Unknown" + return comfy_ui_revision + +def compare_revision(num): + global comfy_ui_revision + if not comfy_ui_revision: + comfy_ui_revision = get_comfyui_revision() + return True if comfy_ui_revision == 'Unknown' or int(comfy_ui_revision) >= num else False def find_nearest_steps(clip_id, prompt): """Find the nearest KSampler or preSampling node that references the given id."""