mirror of
https://github.com/Comfy-Org/ComfyUI-Manager.git
synced 2025-12-16 18:02:58 +08:00
feat: pip fixer for torch, opencv
fixed: Preventing the browser from reopening automatically after a restart on Windows.
This commit is contained in:
parent
4a908d970a
commit
02f1788261
@ -23,7 +23,7 @@ sys.path.append(glob_path)
|
|||||||
import cm_global
|
import cm_global
|
||||||
from manager_util import *
|
from manager_util import *
|
||||||
|
|
||||||
version = [2, 51, 9]
|
version = [2, 52]
|
||||||
version_str = f"V{version[0]}.{version[1]}" + (f'.{version[2]}' if len(version) > 2 else '')
|
version_str = f"V{version[0]}.{version[1]}" + (f'.{version[2]}' if len(version) > 2 else '')
|
||||||
|
|
||||||
|
|
||||||
@ -408,6 +408,7 @@ def execute_install_script(url, repo_path, lazy_mode=False, instant_execution=Fa
|
|||||||
else:
|
else:
|
||||||
if os.path.exists(requirements_path):
|
if os.path.exists(requirements_path):
|
||||||
print("Install: pip packages")
|
print("Install: pip packages")
|
||||||
|
pip_fixer = PIPFixer(get_installed_packages())
|
||||||
with open(requirements_path, "r") as requirements_file:
|
with open(requirements_path, "r") as requirements_file:
|
||||||
for line in requirements_file:
|
for line in requirements_file:
|
||||||
#handle comments
|
#handle comments
|
||||||
@ -430,6 +431,8 @@ def execute_install_script(url, repo_path, lazy_mode=False, instant_execution=Fa
|
|||||||
if package_name.strip() != "" and not package_name.startswith('#'):
|
if package_name.strip() != "" and not package_name.startswith('#'):
|
||||||
try_install_script(url, repo_path, install_cmd, instant_execution=instant_execution)
|
try_install_script(url, repo_path, install_cmd, instant_execution=instant_execution)
|
||||||
|
|
||||||
|
pip_fixer.fix_broken()
|
||||||
|
|
||||||
if os.path.exists(install_script_path):
|
if os.path.exists(install_script_path):
|
||||||
print(f"Install: install script")
|
print(f"Install: install script")
|
||||||
install_cmd = [sys.executable, "install.py"]
|
install_cmd = [sys.executable, "install.py"]
|
||||||
|
|||||||
@ -1216,6 +1216,11 @@ def restart(self):
|
|||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
print(f"\nRestarting... [Legacy Mode]\n\n")
|
print(f"\nRestarting... [Legacy Mode]\n\n")
|
||||||
|
|
||||||
|
sys_argv = sys.argv.copy()
|
||||||
|
if '--windows-standalone-build' in sys_argv:
|
||||||
|
sys_argv.remove('--windows-standalone-build')
|
||||||
|
|
||||||
if sys.platform.startswith('win32'):
|
if sys.platform.startswith('win32'):
|
||||||
return os.execv(sys.executable, ['"' + sys.executable + '"', '"' + sys.argv[0] + '"'] + sys.argv[1:])
|
return os.execv(sys.executable, ['"' + sys.executable + '"', '"' + sys.argv[0] + '"'] + sys.argv[1:])
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
# DON'T USE StrictVersion - cannot handle pre_release version
|
# DON'T USE StrictVersion - cannot handle pre_release version
|
||||||
# try:
|
# try:
|
||||||
# from distutils.version import StrictVersion
|
# from distutils.version import StrictVersion
|
||||||
@ -62,3 +65,150 @@ class StrictVersion:
|
|||||||
def __ne__(self, other):
|
def __ne__(self, other):
|
||||||
return not self == other
|
return not self == other
|
||||||
|
|
||||||
|
|
||||||
|
pip_map = None
|
||||||
|
|
||||||
|
def get_installed_packages(renew=False):
|
||||||
|
global pip_map
|
||||||
|
|
||||||
|
if renew or pip_map is None:
|
||||||
|
try:
|
||||||
|
result = subprocess.check_output([sys.executable, '-m', 'pip', 'list'], universal_newlines=True)
|
||||||
|
|
||||||
|
pip_map = {}
|
||||||
|
for line in result.split('\n'):
|
||||||
|
x = line.strip()
|
||||||
|
if x:
|
||||||
|
y = line.split()
|
||||||
|
if y[0] == 'Package' or y[0].startswith('-'):
|
||||||
|
continue
|
||||||
|
|
||||||
|
pip_map[y[0]] = y[1]
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"[ComfyUI-Manager] Failed to retrieve the information of installed pip packages.")
|
||||||
|
return set()
|
||||||
|
|
||||||
|
return pip_map
|
||||||
|
|
||||||
|
|
||||||
|
def clear_pip_cache():
|
||||||
|
global pip_map
|
||||||
|
pip_map = None
|
||||||
|
|
||||||
|
|
||||||
|
torch_torchvision_version_map = {
|
||||||
|
'2.5.1': '0.20.1',
|
||||||
|
'2.5.0': '0.20.0',
|
||||||
|
'2.4.1': '0.19.1',
|
||||||
|
'2.4.0': '0.19.0',
|
||||||
|
'2.3.1': '0.18.1',
|
||||||
|
'2.3.0': '0.18.0',
|
||||||
|
'2.2.2': '0.17.2',
|
||||||
|
'2.2.1': '0.17.1',
|
||||||
|
'2.2.0': '0.17.0',
|
||||||
|
'2.1.2': '0.16.2',
|
||||||
|
'2.1.1': '0.16.1',
|
||||||
|
'2.1.0': '0.16.0',
|
||||||
|
'2.0.1': '0.15.2',
|
||||||
|
'2.0.0': '0.15.1',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class PIPFixer:
|
||||||
|
def __init__(self, prev_pip_versions):
|
||||||
|
self.prev_pip_versions = { **prev_pip_versions }
|
||||||
|
|
||||||
|
def torch_rollback(self):
|
||||||
|
spec = self.prev_pip_versions['torch'].split('+')
|
||||||
|
if len(spec) > 0:
|
||||||
|
platform = spec[1]
|
||||||
|
else:
|
||||||
|
cmd = [sys.executable, '-m', 'pip', 'install', '--force', 'torch', 'torchvision', 'torchaudio']
|
||||||
|
subprocess.check_output(cmd, universal_newlines=True)
|
||||||
|
print(cmd)
|
||||||
|
return
|
||||||
|
|
||||||
|
torch_ver = StrictVersion(spec[0])
|
||||||
|
torch_ver = f"{torch_ver.major}.{torch_ver.minor}.{torch_ver.patch}"
|
||||||
|
torchvision_ver = torch_torchvision_version_map.get(torch_ver)
|
||||||
|
|
||||||
|
if torchvision_ver is None:
|
||||||
|
cmd = [sys.executable, '-m', 'pip', 'install', '--pre',
|
||||||
|
'torch', 'torchvision', 'torchaudio',
|
||||||
|
'--index-url', f"https://download.pytorch.org/whl/nightly/{platform}"]
|
||||||
|
print("[manager-core] restore PyTorch to nightly version")
|
||||||
|
else:
|
||||||
|
cmd = [sys.executable, '-m', 'pip', 'install',
|
||||||
|
f'torch=={torch_ver}', f'torchvision=={torchvision_ver}', f"torchaudio=={torch_ver}",
|
||||||
|
'--index-url', f"https://download.pytorch.org/whl/{platform}"]
|
||||||
|
print(f"[manager-core] restore PyTorch to {torch_ver}+{platform}")
|
||||||
|
|
||||||
|
subprocess.check_output(cmd, universal_newlines=True)
|
||||||
|
|
||||||
|
def fix_broken(self):
|
||||||
|
new_pip_versions = get_installed_packages(True)
|
||||||
|
|
||||||
|
# remove `comfy` python package
|
||||||
|
try:
|
||||||
|
if 'comfy' in new_pip_versions:
|
||||||
|
cmd = [sys.executable, '-m', 'pip', 'uninstall', 'comfy']
|
||||||
|
subprocess.check_output(cmd, universal_newlines=True)
|
||||||
|
|
||||||
|
print(f"[manager-core] 'comfy' python package is uninstalled.\nWARN: The 'comfy' package is completely unrelated to ComfyUI and should never be installed as it causes conflicts with ComfyUI.")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[manager-core] Failed to uninstall `comfy` python package")
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
# fix torch - reinstall torch packages if version is changed
|
||||||
|
try:
|
||||||
|
if self.prev_pip_versions['torch'] != new_pip_versions['torch'] \
|
||||||
|
or self.prev_pip_versions['torchvision'] != new_pip_versions['torchvision'] \
|
||||||
|
or self.prev_pip_versions['torchaudio'] != new_pip_versions['torchaudio']:
|
||||||
|
self.torch_rollback()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[manager-core] Failed to restore PyTorch")
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
# fix opencv
|
||||||
|
try:
|
||||||
|
ocp = new_pip_versions.get('opencv-contrib-python')
|
||||||
|
ocph = new_pip_versions.get('opencv-contrib-python-headless')
|
||||||
|
op = new_pip_versions.get('opencv-python')
|
||||||
|
oph = new_pip_versions.get('opencv-python-headless')
|
||||||
|
|
||||||
|
versions = [ocp, ocph, op, oph]
|
||||||
|
versions = [StrictVersion(x) for x in versions if x is not None]
|
||||||
|
versions.sort(reverse=True)
|
||||||
|
|
||||||
|
if len(versions) > 0:
|
||||||
|
# upgrade to maximum version
|
||||||
|
targets = []
|
||||||
|
cur = versions[0]
|
||||||
|
if ocp is not None and StrictVersion(ocp) != cur:
|
||||||
|
targets.append('opencv-contrib-python')
|
||||||
|
if ocph is not None and StrictVersion(ocph) != cur:
|
||||||
|
targets.append('opencv-contrib-python-headless')
|
||||||
|
if op is not None and StrictVersion(op) != cur:
|
||||||
|
targets.append('opencv-python')
|
||||||
|
if oph is not None and StrictVersion(oph) != cur:
|
||||||
|
targets.append('opencv-python-headless')
|
||||||
|
|
||||||
|
if len(targets) > 0:
|
||||||
|
for x in targets:
|
||||||
|
cmd = [sys.executable, '-m', 'pip', 'install', f"{x}=={versions[0].version_string}"]
|
||||||
|
subprocess.check_output(cmd, universal_newlines=True)
|
||||||
|
|
||||||
|
print(f"[manager-core] 'opencv' dependencies were fixed: {targets}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[manager-core] Failed to restore opencv")
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
# fix numpy
|
||||||
|
try:
|
||||||
|
np = new_pip_versions.get('numpy')
|
||||||
|
if np is not None:
|
||||||
|
if StrictVersion(np) >= StrictVersion('2'):
|
||||||
|
subprocess.check_output([sys.executable, '-m', 'pip', 'install', f"numpy<2"], universal_newlines=True)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[manager-core] Failed to restore numpy")
|
||||||
|
print(e)
|
||||||
|
|||||||
@ -385,30 +385,7 @@ check_bypass_ssl()
|
|||||||
# Perform install
|
# Perform install
|
||||||
processed_install = set()
|
processed_install = set()
|
||||||
script_list_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "startup-scripts", "install-scripts.txt")
|
script_list_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "startup-scripts", "install-scripts.txt")
|
||||||
pip_map = None
|
pip_fixer = PIPFixer(get_installed_packages())
|
||||||
|
|
||||||
|
|
||||||
def get_installed_packages():
|
|
||||||
global pip_map
|
|
||||||
|
|
||||||
if pip_map is None:
|
|
||||||
try:
|
|
||||||
result = subprocess.check_output([sys.executable, '-m', 'pip', 'list'], universal_newlines=True)
|
|
||||||
|
|
||||||
pip_map = {}
|
|
||||||
for line in result.split('\n'):
|
|
||||||
x = line.strip()
|
|
||||||
if x:
|
|
||||||
y = line.split()
|
|
||||||
if y[0] == 'Package' or y[0].startswith('-'):
|
|
||||||
continue
|
|
||||||
|
|
||||||
pip_map[y[0]] = y[1]
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
print(f"[ComfyUI-Manager] Failed to retrieve the information of installed pip packages.")
|
|
||||||
return set()
|
|
||||||
|
|
||||||
return pip_map
|
|
||||||
|
|
||||||
|
|
||||||
def is_installed(name):
|
def is_installed(name):
|
||||||
@ -620,8 +597,11 @@ if os.path.exists(script_list_path):
|
|||||||
print("\n[ComfyUI-Manager] Startup script completed.")
|
print("\n[ComfyUI-Manager] Startup script completed.")
|
||||||
print("#######################################################################\n")
|
print("#######################################################################\n")
|
||||||
|
|
||||||
|
pip_fixer.fix_broken()
|
||||||
|
|
||||||
del processed_install
|
del processed_install
|
||||||
del pip_map
|
del pip_fixer
|
||||||
|
clear_pip_cache()
|
||||||
|
|
||||||
|
|
||||||
def check_windows_event_loop_policy():
|
def check_windows_event_loop_policy():
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "comfyui-manager"
|
name = "comfyui-manager"
|
||||||
description = "ComfyUI-Manager provides features to install and manage custom nodes for ComfyUI, as well as various functionalities to assist with ComfyUI."
|
description = "ComfyUI-Manager provides features to install and manage custom nodes for ComfyUI, as well as various functionalities to assist with ComfyUI."
|
||||||
version = "2.51.9"
|
version = "2.52"
|
||||||
license = { file = "LICENSE.txt" }
|
license = { file = "LICENSE.txt" }
|
||||||
dependencies = ["GitPython", "PyGithub", "matrix-client==0.4.0", "transformers", "huggingface-hub>0.20", "typer", "rich", "typing-extensions"]
|
dependencies = ["GitPython", "PyGithub", "matrix-client==0.4.0", "transformers", "huggingface-hub>0.20", "typer", "rich", "typing-extensions"]
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user