From 662713f6c2b41bbc2063645ca57cd4e28077c06e Mon Sep 17 00:00:00 2001 From: Hawk Lee Date: Sun, 28 Dec 2025 12:59:28 +0800 Subject: [PATCH] refactor: lazy load all dependencies to prevent eager install checks (v1.4.19) --- aiia_audio_denoise.py | 32 ++++++++++---- aiia_audio_enhance.py | 93 +++++++++++++++++++++++++---------------- aiia_cosyvoice_nodes.py | 74 ++++++++++++++++---------------- pyproject.toml | 2 +- 4 files changed, 120 insertions(+), 81 deletions(-) diff --git a/aiia_audio_denoise.py b/aiia_audio_denoise.py index 1d9a0ce..66420bd 100644 --- a/aiia_audio_denoise.py +++ b/aiia_audio_denoise.py @@ -6,13 +6,27 @@ import subprocess import soundfile as sf import numpy as np -# Auto-install voicefixer if missing -try: - from voicefixer import VoiceFixer -except ImportError: - print("[AIIA] VoiceFixer not found. Installing automatically...") - subprocess.check_call([sys.executable, "-m", "pip", "install", "voicefixer>=0.1.3"]) - from voicefixer import VoiceFixer +# Lazy-loaded globals +VoiceFixer = None + +def _install_voicefixer_if_needed(): + global VoiceFixer + if VoiceFixer is not None: + return + + try: + from voicefixer import VoiceFixer as VF + VoiceFixer = VF + return + except ImportError: + print("[AIIA] VoiceFixer not found. Installing automatically...") + try: + subprocess.check_call([sys.executable, "-m", "pip", "install", "voicefixer>=0.1.3"]) + from voicefixer import VoiceFixer as VF + VoiceFixer = VF + except Exception as e: + print(f"[AIIA] Failed to install voicefixer: {e}") + VoiceFixer = None import shutil import folder_paths @@ -101,6 +115,10 @@ class AIIA_Audio_Denoise: CATEGORY = "AIIA/Audio" def denoise_audio(self, audio, mode, use_cuda, splice_info=None): + _install_voicefixer_if_needed() + if VoiceFixer is None: + raise ImportError("VoiceFixer package is not installed.") + # 1. Initialize Model (Singleton) cuda_available = torch.cuda.is_available() and use_cuda device_str = "cuda" if cuda_available else "cpu" diff --git a/aiia_audio_enhance.py b/aiia_audio_enhance.py index 988a7c3..9d59f6e 100644 --- a/aiia_audio_enhance.py +++ b/aiia_audio_enhance.py @@ -8,44 +8,66 @@ import numpy as np import tempfile from pathlib import Path -# Auto-install resemble-enhance -try: - import resemble_enhance -except ImportError: - print("[AIIA] resemble-enhance not found. Installing without dependencies to protect environment...") - # 1. Install resemble-enhance without dependencies to avoid messing up torch/torchaudio - subprocess.check_call([sys.executable, "-m", "pip", "install", "resemble-enhance", "--no-deps"]) - - # 2. Manually check and install ONLY critical missing non-torch dependencies - # resemble-enhance needs: scipy, torchaudio(present), torch(present), numpy(present), tqdm, etc. - # We assume standard ComfyUI env has torch/numpy/tqdm/Pillow. - pass_packages = ["torch", "torchaudio", "torchvision", "numpy", "scipy", "tqdm"] - # Check if we need to install anything else from its requirements? - # Usually 'hjson' or similar might be missing. - # Let's try to just install the package and let import fail if something helps specific is missing, - # but 'resemble-embed' might be needed? - # Actually, let's just install 'resemble-enhance' + 'gdown' (if used for download) but usually safe. - # To be safe, we can try to install a few lightweight deps if they are missing. - - try: - import hjson - except ImportError: - subprocess.check_call([sys.executable, "-m", "pip", "install", "hjson"]) - - print("[AIIA] resemble-enhance installed.") +# Lazy-loaded globals +enhance = None +denoise = None -# We need to import these AFTER install -try: - # Try updated import structure - from resemble_enhance.enhancer.inference import enhance, denoise -except ImportError: +def _install_resemble_if_needed(): + global enhance, denoise + if enhance is not None: + return + + # Try import first try: - # Fallback for older versions or different structure - from resemble_enhance.inference import enhance, denoise + from resemble_enhance.enhancer.inference import enhance as eh, denoise as dn + enhance = eh + denoise = dn + return except ImportError: - print("[AIIA] Failed to import resemble_enhance. Please install it manually.") - enhance = None - denoise = None + pass + + try: + # Fallback import + from resemble_enhance.inference import enhance as eh, denoise as dn + enhance = eh + denoise = dn + return + except ImportError: + pass + + print("[AIIA] resemble-enhance not found. Installing without dependencies to protect environment...") + try: + # 1. Install resemble-enhance without dependencies + subprocess.check_call([sys.executable, "-m", "pip", "install", "resemble-enhance", "--no-deps"]) + + # 2. Check critical deps + # resemble-enhance needs: scipy, torchaudio(present), torch(present), numpy(present), tqdm, etc. + pass_packages = ["torch", "torchaudio", "torchvision", "numpy", "scipy", "tqdm"] + try: + import hjson + except ImportError: + subprocess.check_call([sys.executable, "-m", "pip", "install", "hjson"]) + + print("[AIIA] resemble-enhance installed.") + + # Retry import + try: + from resemble_enhance.enhancer.inference import enhance as eh, denoise as dn + enhance = eh + denoise = dn + except ImportError: + try: + from resemble_enhance.inference import enhance as eh, denoise as dn + enhance = eh + denoise = dn + except ImportError: + print("[AIIA] Failed to import resemble_enhance even after install.") + enhance = None + denoise = None + + except Exception as e: + print(f"[AIIA] Error installing resemble-enhance: {e}") + def setup_resemble_model_path(): """ @@ -128,6 +150,7 @@ class AIIA_Audio_Enhance: CATEGORY = "AIIA/Audio" def process_audio(self, audio, mode, solver, nfe, tau, denoising, use_cuda, splice_info=None): + _install_resemble_if_needed() if enhance is None: raise ImportError("resemble-enhance library is not available.") diff --git a/aiia_cosyvoice_nodes.py b/aiia_cosyvoice_nodes.py index c827a9f..d127096 100644 --- a/aiia_cosyvoice_nodes.py +++ b/aiia_cosyvoice_nodes.py @@ -9,49 +9,45 @@ import sys import subprocess from huggingface_hub import snapshot_download -def _install_cosyvoice(): - target_install = False +# Lazy-loaded global variable +CosyVoice = None + +def _install_cosyvoice_if_needed(): + global CosyVoice + if CosyVoice is not None: + return + + # Try import first try: - # Check if we can import the class we need - from cosyvoice.cli.cosyvoice import CosyVoice + from cosyvoice.cli.cosyvoice import CosyVoice as CV + CosyVoice = CV return except ImportError: - target_install = True - print("[AIIA] CosyVoice invalid or missing. Attempting robust installation...") + pass + + print("[AIIA] CosyVoice invalid or missing. Attempting robust installation...") + try: + print("[AIIA] Installing CosyVoice from GitHub (latest) to ensure v3 support...") + # Use --no-deps to avoid overriding torch, but install git package + subprocess.check_call([sys.executable, "-m", "pip", "install", "git+https://github.com/FunAudioLLM/CosyVoice.git", "--no-deps", "--force-reinstall"], env=os.environ) - if target_install: - try: - # 1. Try pip install from specific git commit or HEAD if PyPI is broken/outdated - # The pypi 'cosyvoice' seems to be old (0.0.8) and missing 'cli'. - # We need to install from git. - - # Since user just fixed their torch, we MUST use --no-deps to avoid overriding torch. - # But git install often triggers build which needs deps. - # We try to install from github repo directly with --no-deps - - print("[AIIA] Installing CosyVoice from GitHub (latest) to ensure v3 support...") - subprocess.check_call([sys.executable, "-m", "pip", "install", "git+https://github.com/FunAudioLLM/CosyVoice.git", "--no-deps", "--force-reinstall"], env=os.environ) + # Check and install critical sub-dependencies + reqs = ["modelscope", "hyperpyyaml", "onnxruntime", "hjson"] + for r in reqs: + try: + __import__(r) + except ImportError: + print(f"[AIIA] Installing missing dependency: {r}") + subprocess.check_call([sys.executable, "-m", "pip", "install", r], env=os.environ) + + # Retry import + from cosyvoice.cli.cosyvoice import CosyVoice as CV + CosyVoice = CV - # 2. Check and install critical sub-dependencies - reqs = ["modelscope", "hyperpyyaml", "onnxruntime", "hjson"] - for r in reqs: - try: - __import__(r) - except ImportError: - print(f"[AIIA] Installing missing dependency: {r}") - subprocess.check_call([sys.executable, "-m", "pip", "install", r], env=os.environ) - - except Exception as e: - print(f"Failed to install cosyvoice: {e}") - print("Please manually install CosyVoice: 'pip install git+https://github.com/FunAudioLLM/CosyVoice.git --no-deps'") - -_install_cosyvoice() - -try: - from cosyvoice.cli.cosyvoice import CosyVoice -except ImportError as e: - print(f"[AIIA] Critical Error importing CosyVoice: {e}") - CosyVoice = None + except Exception as e: + print(f"Failed to install cosyvoice: {e}") + print("Please manually install CosyVoice: 'pip install git+https://github.com/FunAudioLLM/CosyVoice.git --no-deps'") + class AIIA_CosyVoice_ModelLoader: @classmethod @@ -76,6 +72,8 @@ class AIIA_CosyVoice_ModelLoader: CATEGORY = "AIIA/Loaders" def load_model(self, model_name, use_fp16): + _install_cosyvoice_if_needed() + if CosyVoice is None: raise ImportError("CosyVoice package is not installed. Please install it manually.") diff --git a/pyproject.toml b/pyproject.toml index aff9f28..6ba9f8f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "aiia" description = "A suite of powerful, intuitive, and highly customizable nodes for ComfyUI, featuring a high-performance Media Browser and OOM-safe video tools." -version = "1.4.18" +version = "1.4.19" license = {file = "LICENSE"} readme = "README.md" authors = [