assistanttttttt's picture
Revert "Revert "Revert "Skip re-cloning ComfyUI on restart to speed up startup"""
d1dc2f7
Raw
History Blame Contribute Delete
8.35 kB
import os
import sys
import shutil
from core.settings import *
def move_and_overwrite(src, dst):
if os.path.isdir(src):
if os.path.exists(dst):
shutil.rmtree(dst)
shutil.move(src, dst)
elif os.path.isfile(src):
if os.path.exists(dst):
os.remove(dst)
shutil.move(src, dst)
def initialize_comfyui():
APP_DIR = sys.path[0]
COMFYUI_TEMP_DIR = "ComfyUI_temp"
print("--- Cloning ComfyUI Repository ---")
if not os.path.exists(COMFYUI_TEMP_DIR):
os.system(f"git clone https://github.com/comfy-Org/ComfyUI {COMFYUI_TEMP_DIR}")
print("✅ ComfyUI repository cloned.")
else:
print("✅ ComfyUI repository already exists.")
print(f"--- Merging ComfyUI from '{COMFYUI_TEMP_DIR}' to '{APP_DIR}' ---")
for item in os.listdir(COMFYUI_TEMP_DIR):
src_path = os.path.join(COMFYUI_TEMP_DIR, item)
dst_path = os.path.join(APP_DIR, item)
if item == '.git':
continue
move_and_overwrite(src_path, dst_path)
try:
shutil.rmtree(COMFYUI_TEMP_DIR)
print("✅ ComfyUI merged and temporary directory removed.")
except OSError as e:
print(f"⚠️ Could not remove temporary directory '{COMFYUI_TEMP_DIR}': {e}")
print("--- Cloning third-party extensions for ComfyUI ---")
# 1. ComfyUI_IPAdapter_plus
ipadapter_plus_path = os.path.join(APP_DIR, "custom_nodes", "ComfyUI_IPAdapter_plus")
if not os.path.exists(ipadapter_plus_path):
os.system(f"git clone https://github.com/cubiq/ComfyUI_IPAdapter_plus.git {ipadapter_plus_path}")
print("✅ ComfyUI_IPAdapter_plus extension cloned.")
else:
print("✅ ComfyUI_IPAdapter_plus extension already exists.")
# 2. ComfyUI-InstantX-IPAdapter-SD3
ipadapter_plus_path = os.path.join(APP_DIR, "custom_nodes", "ComfyUI-InstantX-IPAdapter-SD3")
if not os.path.exists(ipadapter_plus_path):
os.system(f"git clone https://github.com/Slickytail/ComfyUI-InstantX-IPAdapter-SD3.git {ipadapter_plus_path}")
print("✅ ComfyUI-InstantX-IPAdapter-SD3 extension cloned.")
else:
print("✅ ComfyUI-InstantX-IPAdapter-SD3 extension already exists.")
# 3. ComfyUI-IPAdapter-Flux
ipadapter_flux_path = os.path.join(APP_DIR, "custom_nodes", "ComfyUI-IPAdapter-Flux")
if not os.path.exists(ipadapter_flux_path):
os.system(f"git clone https://github.com/Shakker-Labs/ComfyUI-IPAdapter-Flux.git {ipadapter_flux_path}")
print("✅ ComfyUI-IPAdapter-Flux extension cloned.")
else:
print("✅ ComfyUI-IPAdapter-Flux extension already exists.")
# 4. ComfyUI-Newbie-Nodes
newbie_nodes_path = os.path.join(APP_DIR, "custom_nodes", "ComfyUI-Newbie-Nodes")
if not os.path.exists(newbie_nodes_path):
os.system(f"git clone https://github.com/NewBieAI-Lab/ComfyUI-Newbie-Nodes.git {newbie_nodes_path}")
print("✅ ComfyUI-Newbie-Nodes extension cloned.")
else:
print("✅ ComfyUI-Newbie-Nodes extension already exists.")
# 5. ComfyUI-Anima-LLLite
anima_controlnet_lllite_nodes_path = os.path.join(APP_DIR, "custom_nodes", "ComfyUI-Anima-LLLite")
if not os.path.exists(anima_controlnet_lllite_nodes_path):
os.system(f"git clone https://github.com/kohya-ss/ComfyUI-Anima-LLLite.git {anima_controlnet_lllite_nodes_path}")
print("✅ ComfyUI-Anima-LLLite extension cloned.")
else:
print("✅ ComfyUI-Anima-LLLite extension already exists.")
print(f"✅ Current working directory is: {os.getcwd()}")
# Ensure torch treats CUDA as unavailable on CPU‑only environment.
import torch
torch.cuda.is_available = lambda: False
# Additional CUDA stubs to prevent calls like torch.cuda.get_device_properties
class _DummyDeviceProps:
def __init__(self):
self.major = 0
self.minor = 0
self.total_memory = 0
def _dummy_get_device_properties(device):
return _DummyDeviceProps()
torch.cuda.get_device_properties = _dummy_get_device_properties
torch.cuda.device_count = lambda: 0
torch.cuda.current_device = lambda: 0
torch.cuda.get_device_name = lambda device: "cpu"
# Apply patch to the external ComfyUI model_management before import.
external_model_mgmt_path = os.path.join(APP_DIR, "comfy", "model_management.py")
if os.path.exists(external_model_mgmt_path):
try:
with open(external_model_mgmt_path, "r", encoding="utf-8") as f:
content = f.read()
start = content.find("def get_torch_device():")
if start != -1:
# Find the end of the function (next def or end of file)
end = content.find("\ndef ", start + 1)
if end == -1:
end = len(content)
new_func = """def get_torch_device():
\"\"\"Return appropriate torch device, falling back to CPU when needed.\"\"\"
global directml_enabled, cpu_state
if directml_enabled:
return directml_device
if cpu_state == CPUState.MPS:
return torch.device(\"mps\")
if cpu_state == CPUState.CPU:
return torch.device(\"cpu\")
if is_intel_xpu():
return torch.device(\"xpu\", torch.xpu.current_device())
if is_ascend_npu():
return torch.device(\"npu\", torch.npu.current_device())
if is_mlu():
return torch.device(\"mlu\", torch.mlu.current_device())
if torch.cuda.is_available():
return torch.device(torch.cuda.current_device())
return torch.device(\"cpu\")
"""
patched_content = content[:start] + new_func + content[end:]
with open(external_model_mgmt_path, "w", encoding="utf-8") as f:
f.write(patched_content)
except Exception as e:
print(f"⚠️ Failed to patch external model_management: {e}")
import comfy.model_management as model_mgmt
# Patch get_torch_device to enforce CPU fallback.
def _cpu_fallback_get_torch_device():
"""Return appropriate torch device, falling back to CPU when needed.
This patch replaces the original implementation that assumed a CUDA GPU
and raised a RuntimeError on CPU‑only systems. It respects the existing
``directml_enabled`` and ``cpu_state`` flags, and falls back to CPU when
no GPU backend is available.
"""
# DirectML path – unchanged.
if model_mgmt.directml_enabled:
return model_mgmt.directml_device
# Apple Silicon / MPS backend.
if model_mgmt.cpu_state == model_mgmt.CPUState.MPS:
return torch.device("mps")
# Explicit CPU request.
if model_mgmt.cpu_state == model_mgmt.CPUState.CPU:
return torch.device("cpu")
# Intel XPU, Ascend NPU, MLU – retain original handling.
if model_mgmt.is_intel_xpu():
return torch.device("xpu", torch.xpu.current_device())
if model_mgmt.is_ascend_npu():
return torch.device("npu", torch.npu.current_device())
if model_mgmt.is_mlu():
return torch.device("mlu", torch.mlu.current_device())
# CUDA – use if available (will be False due to monkey‑patch).
if torch.cuda.is_available():
return torch.device(torch.cuda.current_device())
# Default to CPU.
return torch.device("cpu")
model_mgmt.get_torch_device = _cpu_fallback_get_torch_device
import importlib
importlib.reload(model_mgmt)
# Override should_use_bf16 to avoid any CUDA device property queries on CPU‑only systems.
def _safe_should_use_bf16(device, model_params=None, manual_cast=False):
"""Return False unconditionally – no BF16 support on CPU‑only environment."""
return False
model_mgmt.should_use_bf16 = _safe_should_use_bf16
print("--- Environment Ready ---")
print("✅ ComfyUI initialized with default attention mechanism.")
for dir_path in CATEGORY_TO_DIR_MAP.values():
os.makedirs(os.path.join(APP_DIR, dir_path), exist_ok=True)
os.makedirs(os.path.join(APP_DIR, INPUT_DIR), exist_ok=True)
os.makedirs(os.path.join(APP_DIR, OUTPUT_DIR), exist_ok=True)
print("✅ All required model directories are present.")