diff --git a/Old/sd15_clip_loader.py b/Old/sd15_clip_loader.py new file mode 100644 index 0000000..ff6b231 --- /dev/null +++ b/Old/sd15_clip_loader.py @@ -0,0 +1,68 @@ +import os +from comfy import sd + +class SD15CLIPLoader: + @classmethod + def INPUT_TYPES(cls): + # Path to the 'diffusers/SD15' folder, relative to the script location + script_dir = os.path.dirname(os.path.realpath(__file__)) + base_path = os.path.join(script_dir, "..", "..", "models", "diffusers", "SD15") + print(f"SD15CLIPLoader:Base path: {base_path}") # Debug print + + # Get the list of sub-directories in the 'diffusers/SD15' folder + try: + sub_dirs = [d for d in os.listdir(base_path) if os.path.isdir(os.path.join(base_path, d))] + print(f"Sub-directories: {sub_dirs}") # Debug print + except FileNotFoundError: + sub_dirs = [] + print("SD15CLIPLoader:Base path not found.") # Debug print + + return {"required": {"sub_directory": (sub_dirs,), + "clip_type": (["stable_diffusion", "stable_cascade"],), + }} + + RETURN_TYPES = ("CLIP",) + FUNCTION = "load_clip" + CATEGORY = "DiffusersLoader/SD1.5" + + def load_clip(self, sub_directory, clip_type="stable_diffusion"): + # Determine the clip type + clip_type_enum = sd.CLIPType.STABLE_DIFFUSION + if clip_type == "stable_cascade": + clip_type_enum = sd.CLIPType.STABLE_CASCADE + + # Construct the path to the text_encoder directory + script_dir = os.path.dirname(os.path.realpath(__file__)) + text_encoder_dir = os.path.join(script_dir, "..", "..", "models", "diffusers", "SD15", sub_directory, "text_encoder") + print(f"SD15CLIPLoader:Text encoder directory: {text_encoder_dir}") # Debug print + + # Find the .safetensors or .bin file in the text_encoder directory + text_encoder_file = self.find_model_file(text_encoder_dir) + text_encoder_path = os.path.join(text_encoder_dir, text_encoder_file) + print(f"SD15CLIPLoader:Text encoder path: {text_encoder_path}") # Debug print + + # Ensure the file exists + if not os.path.exists(text_encoder_path): + raise FileNotFoundError(f"SD15CLIPLoader:File not found: {text_encoder_path}") + + # Load the CLIP model using the constructed path + clip = sd.load_clip(ckpt_paths=[text_encoder_path], embedding_directory=os.path.join(script_dir, "..", "..", "models", "diffusers", "SD15", sub_directory, "embeddings"), clip_type=clip_type_enum) + return (clip,) + + @staticmethod + def find_model_file(directory): + for file in os.listdir(directory): + if file.endswith(".safetensors") or file.endswith(".bin"): + return file + raise FileNotFoundError(f"SD15CLIPLoader:No .safetensors file or .bin file found in {directory}") + +# Register the node in the ComfyUI framework +NODE_CLASS_MAPPINGS = { + "SD15CLIPLoader": SD15CLIPLoader, +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "SD15CLIPLoader": "SD1.5 CLIP Loader", +} + +__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"] diff --git a/Old/sd15_combined_loader.py b/Old/sd15_combined_loader.py new file mode 100644 index 0000000..5f160fc --- /dev/null +++ b/Old/sd15_combined_loader.py @@ -0,0 +1,107 @@ +import os +import comfy.sd +import comfy.utils +import torch + +class CombinedDiffusersSD15Loader: + @classmethod + def INPUT_TYPES(cls): + script_dir = os.path.dirname(os.path.realpath(__file__)) + base_path = os.path.join(script_dir, "..", "..", "models", "diffusers", "SD15") + try: + sub_dirs = [d for d in os.listdir(base_path) if os.path.isdir(os.path.join(base_path, d))] + except FileNotFoundError: + sub_dirs = [] + + return {"required": {"sub_directory": (sub_dirs,), + "clip_type": (["stable_diffusion", "stable_cascade"],)}} + + RETURN_TYPES = ("CLIP", "MODEL", "VAE") + FUNCTION = "load_models" + CATEGORY = "DiffusersLoader/SD1.5" + + def load_models(self, sub_directory, clip_type="stable_diffusion"): + clip = self.load_clip(sub_directory, clip_type) + unet = self.load_unet(sub_directory) + vae = self.load_vae(sub_directory) + return clip, unet, vae + + def load_clip(self, sub_directory, clip_type="stable_diffusion"): + clip_type_enum = comfy.sd.CLIPType.STABLE_DIFFUSION + if clip_type == "stable_cascade": + clip_type_enum = comfy.sd.CLIPType.STABLE_CASCADE + + script_dir = os.path.dirname(os.path.realpath(__file__)) + text_encoder_dir = os.path.join(script_dir, "..", "..", "models", "diffusers", "SD15", sub_directory, "text_encoder") + text_encoder_file = self.find_model_file(text_encoder_dir) + text_encoder_path = os.path.join(text_encoder_dir, text_encoder_file) + + if not os.path.exists(text_encoder_path): + raise FileNotFoundError(f"File not found: {text_encoder_path}") + + clip = comfy.sd.load_clip(ckpt_paths=[text_encoder_path], embedding_directory=os.path.join(script_dir, "..", "..", "models", "diffusers", "SD15", sub_directory, "embeddings"), clip_type=clip_type_enum) + return clip + + def load_unet(self, sub_directory): + unet_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'models', 'diffusers', 'SD15', sub_directory, 'unet')) + diffusion_model_path = self.find_model_file(unet_folder) + + if not os.path.exists(diffusion_model_path): + raise FileNotFoundError(f"{os.path.basename(diffusion_model_path)} not found in the directory: {diffusion_model_path}") + + try: + model = comfy.sd.load_unet(diffusion_model_path) + return model + except PermissionError as e: + self.handle_corrupted_file(unet_folder) + raise e + + def load_vae(self, sub_directory): + base_path = self.get_base_path() + vae_folder = os.path.join(base_path, sub_directory, "vae") + vae_filename = self.find_model_file(vae_folder) + vae_path = os.path.join(vae_folder, vae_filename) + full_path = os.path.abspath(vae_path) + + print(f"Attempting to load VAE model from: {full_path}") + + if not os.path.exists(full_path): + raise FileNotFoundError(f"The VAE file '{full_path}' does not exist.") + + sd = comfy.utils.load_torch_file(full_path) + vae = comfy.sd.VAE(sd=sd) + return vae + + @staticmethod + def get_base_path(): + base_path = os.path.join(os.path.dirname(__file__), '..', '..', 'models', 'diffusers', 'SD15') + base_path = os.path.abspath(base_path) + if not os.path.exists(base_path): + raise FileNotFoundError(f"The base path '{base_path}' does not exist.") + return base_path + + @staticmethod + def find_model_file(directory): + for file in os.listdir(directory): + if file.endswith(".safetensors") or file.endswith(".bin"): + return os.path.join(directory, file) + raise FileNotFoundError(f"No .safetensors file or . bin file found in {directory}") + + @staticmethod + def handle_corrupted_file(unet_folder): + corrupted_path = unet_folder + ".corrupted" + try: + os.rename(unet_folder, corrupted_path) + except Exception as e: + raise e + +# Register the node in the ComfyUI framework +NODE_CLASS_MAPPINGS = { + "CombinedDiffusersSD15Loader": CombinedDiffusersSD15Loader, +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "CombinedDiffusersSD15Loader": "Combined Diffusers SD1.5 Loader", +} + +__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"] diff --git a/Old/sd15_unet_loader.py b/Old/sd15_unet_loader.py new file mode 100644 index 0000000..688eb66 --- /dev/null +++ b/Old/sd15_unet_loader.py @@ -0,0 +1,73 @@ +import os +import comfy.sd + +def get_sub_directory_list(base_path): + """Returns a list of sub-directories within the given base path.""" + base_directory = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'models', base_path)) + print(f"SD15UNETLoader:Looking for sub-directories in: {base_directory}") + + if os.path.exists(base_directory): + sub_dirs = [d for d in os.listdir(base_directory) if os.path.isdir(os.path.join(base_directory, d))] + print(f"SD15UNETLoader:Found sub-directories: {sub_dirs}") + return sub_dirs + else: + print(f"SD15UNETLoader:Path does not exist: {base_directory}") + return [] + +def handle_corrupted_file(unet_folder): + """Handle corrupted UNET folder by renaming it and logging the action.""" + corrupted_path = unet_folder + ".corrupted" + try: + os.rename(unet_folder, corrupted_path) + print(f"SD15UNETLoader:Moved corrupted folder to: {corrupted_path}") + except PermissionError as e: + print(f"SD15UNETLoader:PermissionError while moving corrupted folder: {e}") + raise PermissionError(f"SD15UNETLoader:Permission denied while moving: {unet_folder}") + except Exception as e: + print(f"SD15UNETLoader:Error while moving corrupted folder: {e}") + raise e + +class SD15UNETLoader: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "sub_directory": (get_sub_directory_list("diffusers/SD15"),), + } + } + + RETURN_TYPES = ("MODEL",) + FUNCTION = "load_unet" + CATEGORY = "DiffusersLoader/SD1.5" + + def load_unet(self, sub_directory): + unet_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'models', 'diffusers', 'SD15', sub_directory, 'unet')) + diffusion_model_path = self.find_model_file(unet_folder) + print(f"SD15UNETLoader:Attempting to load UNET model from: {diffusion_model_path}") + + if not os.path.exists(diffusion_model_path): + raise FileNotFoundError(f"{os.path.basename(diffusion_model_path)} not found in the directory: {diffusion_model_path}") + + try: + model = comfy.sd.load_unet(diffusion_model_path) + return (model,) + except PermissionError as e: + print(f"SD15UNETLoader:PermissionError: {e}") + raise PermissionError(f"SD15UNETLoader:Permission denied: {diffusion_model_path}") + except Exception as e: + print(f"SD15UNETLoader:Error loading UNET model: {e}") + handle_corrupted_file(unet_folder) + raise e + + @staticmethod + def find_model_file(directory): + for file in os.listdir(directory): + if file.endswith(".safetensors") or file.endswith(".bin"): + return os.path.join(directory, file) + raise FileNotFoundError(f"SD15UNETLoader:No .safetensors file or .bin file found in {directory}") + +# Ensure the node is registered properly +NODE_CLASS_MAPPINGS = {"SD15UNETLoader": SD15UNETLoader} +NODE_DISPLAY_NAME_MAPPINGS = {"SD15UNETLoader": "SD1.5 UNET Loader"} + +__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"] diff --git a/Old/sd15_vae_loader.py b/Old/sd15_vae_loader.py new file mode 100644 index 0000000..c9433ec --- /dev/null +++ b/Old/sd15_vae_loader.py @@ -0,0 +1,60 @@ +import os +import comfy.utils +import torch + +class SD15VAELoader: + @staticmethod + def get_base_path(): + # Adjust the base path to the location where the SD15 subdirectory is located + base_path = os.path.join(os.path.dirname(__file__), '..', '..', 'models', 'diffusers', 'SD15') + base_path = os.path.abspath(base_path) # Convert to absolute path + if not os.path.exists(base_path): + raise FileNotFoundError(f"The base path '{base_path}' does not exist.") + return base_path + + @staticmethod + def get_subdirectories(): + base_path = SD15VAELoader.get_base_path() + return [name for name in os.listdir(base_path) if os.path.isdir(os.path.join(base_path, name))] + + @staticmethod + def find_model_file(directory): + for file in os.listdir(directory): + if file.endswith(".safetensors") or file.endswith(".bin"): + return file + raise FileNotFoundError(f"No .safetensors file or .bin file found in {directory}") + + @classmethod + def INPUT_TYPES(cls): + subdirectories = cls.get_subdirectories() + return { + "required": { + "sub_directory": (subdirectories, ), + } + } + + RETURN_TYPES = ("VAE",) + FUNCTION = "load_vae" + CATEGORY = "DiffusersLoader/SD1.5" + + def load_vae(self, sub_directory): + base_path = self.get_base_path() + vae_folder = os.path.join(base_path, sub_directory, "vae") + vae_filename = self.find_model_file(vae_folder) + vae_path = os.path.join(vae_folder, vae_filename) + full_path = os.path.abspath(vae_path) + + print(f"Attempting to load VAE model from: {full_path}") + + if not os.path.exists(full_path): + raise FileNotFoundError(f"The VAE file '{full_path}' does not exist.") + + sd = comfy.utils.load_torch_file(full_path) + vae = comfy.sd.VAE(sd=sd) + return (vae,) + +# Ensure the node is registered properly +NODE_CLASS_MAPPINGS = {"SD15VAELoader": SD15VAELoader} +NODE_DISPLAY_NAME_MAPPINGS = {"SD15VAELoader": "SD1.5 VAE Loader"} + +__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"] diff --git a/Old/sdxl_clip_loader.py b/Old/sdxl_clip_loader.py new file mode 100644 index 0000000..07ae938 --- /dev/null +++ b/Old/sdxl_clip_loader.py @@ -0,0 +1,69 @@ +import os +from comfy import sd + +class SDXLCLIPLoader: + @classmethod + def INPUT_TYPES(cls): + script_dir = os.path.dirname(os.path.realpath(__file__)) + base_path = os.path.abspath(os.path.join(script_dir, "../../models/diffusers/SDXL")) + print(f"SDXLCLIPLoader: Base path for SDXL models: {base_path}") + + if not os.path.exists(base_path): + raise FileNotFoundError(f"SDXLCLIPLoader: The base path {base_path} does not exist.") + + sub_dirs = [d for d in os.listdir(base_path) if os.path.isdir(os.path.join(base_path, d))] + print(f"SDXLCLIPLoader: Available subdirectories: {sub_dirs}") + return { + "required": { + "sub_directory": (sub_dirs, ), + } + } + + RETURN_TYPES = ("CLIP",) + FUNCTION = "load_sdxl_clip" + CATEGORY = "DiffusersLoader/SDXL" + + def load_sdxl_clip(self, sub_directory): + script_dir = os.path.dirname(os.path.realpath(__file__)) + base_path = os.path.abspath(os.path.join(script_dir, "../../models/diffusers/SDXL", sub_directory)) + + text_encoder_dir1 = os.path.join(base_path, "text_encoder") + text_encoder_dir2 = os.path.join(base_path, "text_encoder_2") + + text_encoder_file1 = self.find_model_file(text_encoder_dir1) + text_encoder_file2 = self.find_model_file(text_encoder_dir2) + + text_encoder_path1 = os.path.join(text_encoder_dir1, text_encoder_file1) + text_encoder_path2 = os.path.join(text_encoder_dir2, text_encoder_file2) + + print(f"SDXLCLIPLoader: Checking paths:\n{text_encoder_path1}\n{text_encoder_path2}") + + path1_exists = os.path.exists(text_encoder_path1) + path2_exists = os.path.exists(text_encoder_path2) + + print(f"SDXLCLIPLoader: Path 1 exists: {path1_exists}") + print(f"SDXLCLIPLoader: Path 2 exists: {path2_exists}") + + if not path1_exists or not path2_exists: + raise FileNotFoundError(f"SDXLCLIPLoader: One or both text encoder files not found in {base_path}") + + clip = sd.load_clip(ckpt_paths=[text_encoder_path1, text_encoder_path2], embedding_directory=os.path.join(base_path, "embeddings")) + return (clip,) + + @staticmethod + def find_model_file(directory): + for file in os.listdir(directory): + if file.endswith(".safetensors") or file.endswith(".bin"): + return file + raise FileNotFoundError(f"No .safetensors file found in {directory}") + +# Mapping the node to make it recognizable in the ComfyUI framework +NODE_CLASS_MAPPINGS = { + "SDXLCLIPLoader": SDXLCLIPLoader, +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "SDXLCLIPLoader": "SDXL CLIP Loader", +} + +__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"] diff --git a/Old/sdxl_combined_loader.py b/Old/sdxl_combined_loader.py new file mode 100644 index 0000000..a0307a1 --- /dev/null +++ b/Old/sdxl_combined_loader.py @@ -0,0 +1,101 @@ +import os +import comfy.utils +import comfy.sd +import torch + +class CombinedDiffusersSDXLLoader: + @staticmethod + def get_base_path(): + base_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'models', 'diffusers', 'SDXL')) + if not os.path.exists(base_path): + raise FileNotFoundError(f"CombinedDiffusersSDXLLoader: The base path '{base_path}' does not exist.") + return base_path + + @staticmethod + def get_subdirectories(): + base_path = CombinedDiffusersSDXLLoader.get_base_path() + return [name for name in os.listdir(base_path) if os.path.isdir(os.path.join(base_path, name))] + + @staticmethod + def find_model_file(directory): + for file in os.listdir(directory): + if file.endswith(".safetensors") or file.endswith(".bin"): + return os.path.join(directory, file) + raise FileNotFoundError(f"CombinedDiffusersSDXLLoader: No .safetensors file or .bin file found in {directory}") + + @classmethod + def INPUT_TYPES(cls): + subdirectories = cls.get_subdirectories() + return { + "required": { + "sub_directory": (subdirectories, ), + } + } + + RETURN_TYPES = ("MODEL", "CLIP", "VAE") + FUNCTION = "load_models" + CATEGORY = "DiffusersLoader/SDXL" + + def load_models(self, sub_directory): + base_path = self.get_base_path() + sub_dir_path = os.path.join(base_path, sub_directory) + + vae_model = self.load_vae(sub_dir_path) + unet_model = self.load_unet(sub_dir_path) + clip_model = self.load_clip(sub_dir_path) + + return unet_model, clip_model, vae_model + + def load_vae(self, base_path): + vae_folder = os.path.join(base_path, "vae") + vae_path = self.find_model_file(vae_folder) + print(f"CombinedDiffusersSDXLLoader: Attempting to load VAE model from: {vae_path}") + + vae_sd = comfy.utils.load_torch_file(vae_path) + return comfy.sd.VAE(sd=vae_sd) + + def load_unet(self, base_path): + unet_folder = os.path.join(base_path, 'unet') + unet_path = self.find_model_file(unet_folder) + print(f"CombinedDiffusersSDXLLoader: Attempting to load UNET model from: {unet_path}") + + try: + return comfy.sd.load_unet(unet_path) + except PermissionError as e: + print(f"PermissionError: {e}") + raise PermissionError(f"CombinedDiffusersSDXLLoader: Permission denied: {unet_path}") + except Exception as e: + print(f"CombinedDiffusersSDXLLoader: Error loading UNET model: {e}") + self.handle_corrupted_file(unet_folder) + raise e + + def load_clip(self, base_path): + text_encoder_dir1 = os.path.join(base_path, "text_encoder") + text_encoder_dir2 = os.path.join(base_path, "text_encoder_2") + + text_encoder_path1 = self.find_model_file(text_encoder_dir1) + text_encoder_path2 = self.find_model_file(text_encoder_dir2) + + print(f"CombinedDiffusersSDXLLoader: Checking paths:\n{text_encoder_path1}\n{text_encoder_path2}") + + return comfy.sd.load_clip(ckpt_paths=[text_encoder_path1, text_encoder_path2], embedding_directory=os.path.join(base_path, "embeddings")) + + @staticmethod + def handle_corrupted_file(unet_folder): + """Handle corrupted UNET folder by renaming it and logging the action.""" + corrupted_path = unet_folder + ".corrupted" + try: + os.rename(unet_folder, corrupted_path) + print(f"CombinedDiffusersSDXLLoader: Moved corrupted folder to: {corrupted_path}") + except PermissionError as e: + print(f"CombinedDiffusersSDXLLoader: PermissionError while moving corrupted folder: {e}") + raise PermissionError(f"Permission denied while moving: {unet_folder}") + except Exception as e: + print(f"CombinedDiffusersSDXLLoader: Error while moving corrupted folder: {e}") + raise e + +# Ensure the node is registered properly +NODE_CLASS_MAPPINGS = {"CombinedDiffusersSDXLLoader": CombinedDiffusersSDXLLoader} +NODE_DISPLAY_NAME_MAPPINGS = {"CombinedDiffusersSDXLLoader": "Combined Diffusers SDXL Loader"} + +__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"] diff --git a/Old/sdxl_unet_loader.py b/Old/sdxl_unet_loader.py new file mode 100644 index 0000000..4b9f0fb --- /dev/null +++ b/Old/sdxl_unet_loader.py @@ -0,0 +1,78 @@ +import os +import comfy.sd + +def get_sub_directory_list(base_path): + """Returns a list of sub-directories within the given base path.""" + base_directory = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'models', base_path)) + print(f"SDXLUNETLoader:Looking for sub-directories in: {base_directory}") + + if os.path.exists(base_directory): + sub_dirs = [d for d in os.listdir(base_directory) if os.path.isdir(os.path.join(base_directory, d))] + print(f"SDXLUNETLoader:Found sub-directories: {sub_dirs}") + return sub_dirs + else: + print(f"SDXLUNETLoader:Path does not exist: {base_directory}") + return [] + +def handle_corrupted_file(unet_folder): + """Handle corrupted UNET folder by renaming it and logging the action.""" + corrupted_path = unet_folder + ".corrupted" + try: + os.rename(unet_folder, corrupted_path) + print(f"SDXLUNETLoader:Moved corrupted folder to: {corrupted_path}") + except PermissionError as e: + print(f"SDXLUNETLoader:PermissionError while moving corrupted folder: {e}") + raise PermissionError(f"Permission denied while moving: {unet_folder}") + except Exception as e: + print(f"SDXLUNETLoader:Error while moving corrupted folder: {e}") + raise e + +class SDXLUNETLoader: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "sub_directory": (get_sub_directory_list("diffusers/SDXL"),), + } + } + + RETURN_TYPES = ("MODEL",) + FUNCTION = "load_unet" + CATEGORY = "DiffusersLoader/SDXL" + + def load_unet(self, sub_directory): + unet_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'models', 'diffusers', 'SDXL', sub_directory, 'unet')) + diffusion_model_path = self.find_model_file(unet_folder) + print(f"SDXLUNETLoader:Attempting to load UNET model from: {diffusion_model_path}") + + if not os.path.exists(diffusion_model_path): + raise FileNotFoundError(f"SDXLUNETLoader:{os.path.basename(diffusion_model_path)} not found in the directory: {diffusion_model_path}") + + try: + model = comfy.sd.load_unet(diffusion_model_path) + return (model,) + except PermissionError as e: + print(f"PermissionError: {e}") + raise PermissionError(f"SDXLUNETLoader:Permission denied: {diffusion_model_path}") + except Exception as e: + print(f"SDXLUNETLoader:Error loading UNET model: {e}") + handle_corrupted_file(unet_folder) + raise e + + @staticmethod + def find_model_file(directory): + for file in os.listdir(directory): + if file.endswith(".safetensors") or file.endswith(".bin"): + return os.path.join(directory, file) + raise FileNotFoundError(f"SDXLUNETLoader:No .safetensors file or .bin file found in {directory}") + +# Mapping the node to make it recognizable in the ComfyUI framework +NODE_CLASS_MAPPINGS = { + "SDXLUNETLoader": SDXLUNETLoader, +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "SDXLUNETLoader": "SDXL UNET Loader", +} + +__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"] diff --git a/Old/sdxl_vae_loader.py b/Old/sdxl_vae_loader.py new file mode 100644 index 0000000..283b868 --- /dev/null +++ b/Old/sdxl_vae_loader.py @@ -0,0 +1,60 @@ +import os +import comfy.utils +import torch + +class SDXLVAELoader: + @staticmethod + def get_base_path(): + # Adjust the base path to the location where the SDXL subdirectory is located + base_path = os.path.join(os.path.dirname(__file__), '..', '..', 'models', 'diffusers', 'SDXL') + base_path = os.path.abspath(base_path) # Convert to absolute path + if not os.path.exists(base_path): + raise FileNotFoundError(f"SDXLVAELoader:The base path '{base_path}' does not exist.") + return base_path + + @staticmethod + def get_subdirectories(): + base_path = SDXLVAELoader.get_base_path() + return [name for name in os.listdir(base_path) if os.path.isdir(os.path.join(base_path, name))] + + @staticmethod + def find_model_file(directory): + for file in os.listdir(directory): + if file.endswith(".safetensors") or file.endswith(".bin"): + return file + raise FileNotFoundError(f"SDXLVAELoader:No .safetensors file or .bin file found in {directory}") + + @classmethod + def INPUT_TYPES(cls): + subdirectories = cls.get_subdirectories() + return { + "required": { + "sub_directory": (subdirectories, ), + } + } + + RETURN_TYPES = ("VAE",) + FUNCTION = "load_vae" + CATEGORY = "DiffusersLoader/SDXL" + + def load_vae(self, sub_directory): + base_path = self.get_base_path() + vae_folder = os.path.join(base_path, sub_directory, "vae") + vae_filename = self.find_model_file(vae_folder) + vae_path = os.path.join(vae_folder, vae_filename) + full_path = os.path.abspath(vae_path) + + print(f"SDXLVAELoader:Attempting to load VAE model from: {full_path}") + + if not os.path.exists(full_path): + raise FileNotFoundError(f"SDXLVAELoader:The VAE file '{full_path}' does not exist.") + + sd = comfy.utils.load_torch_file(full_path) + vae = comfy.sd.VAE(sd=sd) + return (vae,) + +# Ensure the node is registered properly +NODE_CLASS_MAPPINGS = {"SDXLVAELoader": SDXLVAELoader} +NODE_DISPLAY_NAME_MAPPINGS = {"SDXLVAELoader": "SDXL VAE Loader"} + +__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"] diff --git a/README.md b/README.md index eefd666..5ddf927 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ This project was created to understand how the DiffusersLoader avaliable in comf This project provides tools and loaders for integrating diffusers format checkpoint models with ComfyUI. It helps users who already have diffusers format checkpoints to seamlessly use them without needing to convert them to the standard format. + ## Installation Follow these steps to install and set up the project: @@ -24,43 +25,32 @@ Follow these steps to install and set up the project: ![image](https://github.com/Scorpinaus/ComfyUI-DiffusersLoader/assets/85672737/f4e962f9-aee3-4027-9e8b-c559451cf819) 2. Add nodes to your workflow by: - - Add Nodes -> DiffusersLoader -> SD1.5 or SDXL -> Select your nodes + - Add Nodes -> DiffusersLoader -> Combined -> CombinedDiffusersLoader - ![image](https://github.com/Scorpinaus/ComfyUI-DiffusersLoader/assets/85672737/68c3232d-7f05-4a48-88a7-f7498ac2139c) - ![image](https://github.com/Scorpinaus/ComfyUI-DiffusersLoader/assets/85672737/a83724a1-9afb-467a-b3d4-9006afcc6557) ## Features -There are 2 main areas of this node package: SD1.5 Loaders and SDXL Loaders. - -### Set-up - -For the nodes to work, you will need to create SD15 and SDXL sub-directories under the diffusers folder as seen below: - -![image](https://github.com/Scorpinaus/ComfyUI-DiffusersLoader/assets/85672737/b6d779da-5481-4666-ba24-faf2063ee76d) ![image](https://github.com/Scorpinaus/ComfyUI-DiffusersLoader/assets/85672737/7f71b2bd-172b-4380-9653-a1a2d0a09799) - -Put your converted diffusers model into either SD15 for SD1.5 models or SDXL for SDXL models. - -### Stable Diffusion 1.5 Loaders - -There are 4 main nodes: - -![image](https://github.com/Scorpinaus/ComfyUI-DiffusersLoader/assets/85672737/93e8627d-4827-45cc-af98-3f9182133339) - - -### Stable Diffusion XL Loaders - -There are 4 main nodes: - -![image](https://github.com/Scorpinaus/ComfyUI-DiffusersLoader/assets/85672737/0d3121b6-ba7f-47fb-94a3-018c656598fe) +The CombinedDiffusersLoader supports loading of diffusers checkpoints for: +- SD1.5 +- SDXL +- SD3 ### Workflow Example The combined loader work in the same manner as existing checkpoints loader as seen in this workflow: ![image](https://github.com/Scorpinaus/ComfyUI-DiffusersLoader/assets/85672737/6b079ac4-1479-43e2-87f6-879919e34d0b) +Select the name of the diffusers checkpoint folder from the dropdown list and connect the nodes. + +Take note for SD3: +- You have the option for the T5 encoder (text_encoder_3) to select either part_1, part_2, or all (both). +- Selecting all will create a combined T5 encoder in the same folder named combined_text_encoder.safetensors for the first use. + ## Limitations & Future Improvements -The combined loader and CLIP loader does not work for inpainting models. +Future improvements is to update the seperate VAE, CLIP and UNET loaders. + ## Contributing @@ -69,8 +59,7 @@ Contributions are always welcome! Please follow the contributing guidelines to s ## License This project is licensed under the MIT License. -## Contact - +## Contact the Author Hafiz Saffie - hafiz.safs@gmail.com Project Link: https://github.com/Scorpinaus/ComfyUI-DiffusersLoader