Download custom_nodes/Comfyui-Memory_Cleanup/__init__.py from hipinis/comfyui-config: direct link, hf CLI and curl.
- Browser
- Download file 5.58 kB
-
https://huggingface.co/hipinis/comfyui-config/resolve/main/custom_nodes/Comfyui-Memory_Cleanup/__init__.py
- Command line
-
hf download hf://hipinis/comfyui-config/custom_nodes/Comfyui-Memory_Cleanup/__init__.py
-
curl -L -o __init__.py https://huggingface.co/hipinis/comfyui-config/resolve/main/custom_nodes/Comfyui-Memory_Cleanup/__init__.py
5.58 kB
| import psutil | |
| import ctypes | |
| from ctypes import wintypes | |
| import time | |
| import platform | |
| import gc | |
| from server import PromptServer | |
| import comfy.model_management | |
| class AnyType(str): | |
| """用于表示任意类型的特殊类,在类型比较时总是返回相等""" | |
| def __eq__(self, _) -> bool: | |
| return True | |
| def __ne__(self, __value: object) -> bool: | |
| return False | |
| any = AnyType("*") | |
| class VRAMCleanup: | |
| def INPUT_TYPES(s): | |
| return { | |
| "required": { | |
| "offload_model": ("BOOLEAN", {"default": True}), | |
| "offload_cache": ("BOOLEAN", {"default": True}), | |
| }, | |
| "optional": { | |
| "anything": (any, {}), | |
| }, | |
| "hidden": { | |
| "unique_id": "UNIQUE_ID", | |
| "extra_pnginfo": "EXTRA_PNGINFO", | |
| } | |
| } | |
| RETURN_TYPES = (any,) | |
| RETURN_NAMES = ("output",) | |
| OUTPUT_NODE = True | |
| FUNCTION = "empty_cache" | |
| CATEGORY = "Memory Management" | |
| def IS_CHANGED(s, **kwargs): | |
| # 返回当前时间戳,确保每次都执行 | |
| return float(time.time()) | |
| def empty_cache(self, offload_model, offload_cache, anything=None, unique_id=None, extra_pnginfo=None): | |
| try: | |
| if offload_model: | |
| comfy.model_management.unload_all_models() | |
| if offload_cache: | |
| gc.collect() | |
| comfy.model_management.soft_empty_cache() | |
| PromptServer.instance.prompt_queue.set_flag("free_memory", True) | |
| print(f"VRAM清理完成 [卸载模型: {offload_model}, 清空缓存: {offload_cache}]") | |
| except Exception as e: | |
| print(f"VRAM清理失败: {str(e)}") | |
| return (anything,) | |
| class RAMCleanup: | |
| def INPUT_TYPES(s): | |
| return { | |
| "required": { | |
| "clean_file_cache": ("BOOLEAN", {"default": True, "label": "清理文件缓存"}), | |
| "clean_processes": ("BOOLEAN", {"default": True, "label": "清理进程内存"}), | |
| "clean_dlls": ("BOOLEAN", {"default": True, "label": "清理未使用DLL"}), | |
| "retry_times": ("INT", { | |
| "default": 3, | |
| "min": 1, | |
| "max": 10, | |
| "step": 1, | |
| "label": "重试次数" | |
| }), | |
| }, | |
| "optional": { | |
| "anything": (any, {}), | |
| }, | |
| "hidden": { | |
| "unique_id": "UNIQUE_ID", | |
| "extra_pnginfo": "EXTRA_PNGINFO", | |
| } | |
| } | |
| RETURN_TYPES = (any,) | |
| RETURN_NAMES = ("output",) | |
| OUTPUT_NODE = True | |
| FUNCTION = "clean_ram" | |
| CATEGORY = "Memory Management" | |
| def IS_CHANGED(s, **kwargs): | |
| # 返回当前时间戳,确保每次都执行 | |
| return float(time.time()) | |
| def get_ram_usage(self): | |
| memory = psutil.virtual_memory() | |
| return memory.percent, memory.available / (1024 * 1024) | |
| def clean_ram(self, clean_file_cache, clean_processes, clean_dlls, retry_times, anything=None, unique_id=None, extra_pnginfo=None): | |
| try: | |
| before_usage, before_available = self.get_ram_usage() | |
| system = platform.system() | |
| for attempt in range(retry_times): | |
| if clean_file_cache: | |
| try: | |
| if system == "Windows": | |
| ctypes.windll.kernel32.SetSystemFileCacheSize(-1, -1, 0) | |
| elif system == "Linux": | |
| libc = ctypes.CDLL("libc.so.6") | |
| libc.malloc_trim(0) | |
| except: | |
| pass | |
| if clean_processes: | |
| if system == "Windows": | |
| for process in psutil.process_iter(['pid', 'name']): | |
| try: | |
| handle = ctypes.windll.kernel32.OpenProcess( | |
| wintypes.DWORD(0x001F0FFF), | |
| wintypes.BOOL(False), | |
| wintypes.DWORD(process.info['pid']) | |
| ) | |
| ctypes.windll.psapi.EmptyWorkingSet(handle) | |
| ctypes.windll.kernel32.CloseHandle(handle) | |
| except: | |
| continue | |
| if clean_dlls: | |
| try: | |
| if system == "Windows": | |
| ctypes.windll.kernel32.SetProcessWorkingSetSize(-1, -1, -1) | |
| except: | |
| pass | |
| time.sleep(1) | |
| after_usage, after_available = self.get_ram_usage() | |
| freed_mb = after_available - before_available | |
| print(f"RAM清理完成 [{before_usage:.1f}% → {after_usage:.1f}%, 释放: {freed_mb:.0f}MB]") | |
| except Exception as e: | |
| print(f"RAM清理失败: {str(e)}") | |
| return (anything,) | |
| NODE_CLASS_MAPPINGS = { | |
| "VRAMCleanup": VRAMCleanup, | |
| "RAMCleanup": RAMCleanup, | |
| } | |
| NODE_DISPLAY_NAME_MAPPINGS = { | |
| "VRAMCleanup": "🎈VRAM-Cleanup", | |
| "RAMCleanup": "🎈RAM-Cleanup", | |
| } | |