import os import sys import site # ================= 强力 CPU 类型代理补丁 (Proxy-based Monkey Patch) ================= # 抢在任何 ComfyUI 或 PyTorch 后端逻辑加载前,完成对底层类型的替换 if "--use-sage-attention" in sys.argv: sys.argv.remove("--use-sage-attention") if "--cpu" not in sys.argv: sys.argv.append("--cpu") os.environ["CUDA_VISIBLE_DEVICES"] = "-1" os.environ["FORCE_CPU"] = "1" try: import torch # 1. 彻底架空 CUDA 状态查询 torch.cuda.is_available = lambda: False torch.cuda.device_count = lambda: 0 torch.cuda.current_device = lambda: 0 # 备份原始的 torch.device 类型(用于底层真正的实例化) _orig_device = torch.device # 2. 构造一个完美的代理类,既是正统的 'type' 身份,又能动态重定向 class TorchDeviceProxy: def __new__(cls, *args, **kwargs): # 核心掉包逻辑:只要触碰 cuda,一律无缝替换为 cpu if args and isinstance(args[0], str) and 'cuda' in args[0]: return _orig_device('cpu') try: return _orig_device(*args, **kwargs) except Exception: return _orig_device('cpu') # 补全可能用到的类属性,使其在静态类型检查或 isinstance 检查时完美伪装 @property def __class__(self): return _orig_device # 3. 将原类的关键标识和名称无缝同步给代理类,欺骗 `str | torch.device` 表达式 TorchDeviceProxy.__name__ = _orig_device.__name__ TorchDeviceProxy.__module__ = _orig_device.__module__ TorchDeviceProxy.__qualname__ = _orig_device.__qualname__ # 替换全局 torch.device torch.device = TorchDeviceProxy print("🤖 [CPU Patch] Successfully deployed seamless TorchDeviceProxy class.") except Exception as e: print(f"⚠️ [CPU Patch] Error while generating proxy patch: {e}") # ==================================================================== try: import spaces except ImportError: spaces = None APP_DIR = os.path.dirname(os.path.abspath(__file__)) if APP_DIR not in sys.path: sys.path.insert(0, APP_DIR) def apply_sage_attention_patch(): print("--- [Runtime Patch] 🤖 CPU mode. SageAttention disabled. ---") return "Skipped (CPU Mode)" def dummy_gpu_decorator(func): return func @dummy_gpu_decorator def dummy_gpu_for_startup(): print("--- [GPU Startup] Bypassed for CPU mode. ---") return "Bypassed" def main(): from comfy_integration import setup as setup_comfyui from utils.app_utils import load_ipadapter_presets print("--- [Setup] Starting ComfyUI initialization ---") try: setup_comfyui.initialize_comfyui() except Exception as e: print(f"🚨 [Init Error] ComfyUI initialization failed: {e}") raise e print("--- [Setup] Reloading site-packages... ---") try: site.main() except Exception: pass print("--- Starting Application Setup ---") load_ipadapter_presets() from ui.layout import build_ui from ui.events import attach_event_handlers demo = build_ui(attach_event_handlers) print("--- Launching Gradio Interface ---") demo.queue().launch(server_name="0.0.0.0", server_port=7860) if __name__ == "__main__": main()