mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-01-23 04:40:15 +08:00
Merge branch 'comfyanonymous:master' into master
This commit is contained in:
commit
970b7fb84f
@ -29,18 +29,48 @@ def frontend_install_warning_message():
|
|||||||
This error is happening because the ComfyUI frontend is no longer shipped as part of the main repo but as a pip package instead.
|
This error is happening because the ComfyUI frontend is no longer shipped as part of the main repo but as a pip package instead.
|
||||||
""".strip()
|
""".strip()
|
||||||
|
|
||||||
|
def parse_version(version: str) -> tuple[int, int, int]:
|
||||||
|
return tuple(map(int, version.split(".")))
|
||||||
|
|
||||||
|
def is_valid_version(version: str) -> bool:
|
||||||
|
"""Validate if a string is a valid semantic version (X.Y.Z format)."""
|
||||||
|
pattern = r"^(\d+)\.(\d+)\.(\d+)$"
|
||||||
|
return bool(re.match(pattern, version))
|
||||||
|
|
||||||
|
def get_installed_frontend_version():
|
||||||
|
"""Get the currently installed frontend package version."""
|
||||||
|
frontend_version_str = version("comfyui-frontend-package")
|
||||||
|
return frontend_version_str
|
||||||
|
|
||||||
|
def get_required_frontend_version():
|
||||||
|
"""Get the required frontend version from requirements.txt."""
|
||||||
|
try:
|
||||||
|
with open(requirements_path, "r", encoding="utf-8") as f:
|
||||||
|
for line in f:
|
||||||
|
line = line.strip()
|
||||||
|
if line.startswith("comfyui-frontend-package=="):
|
||||||
|
version_str = line.split("==")[-1]
|
||||||
|
if not is_valid_version(version_str):
|
||||||
|
logging.error(f"Invalid version format in requirements.txt: {version_str}")
|
||||||
|
return None
|
||||||
|
return version_str
|
||||||
|
logging.error("comfyui-frontend-package not found in requirements.txt")
|
||||||
|
return None
|
||||||
|
except FileNotFoundError:
|
||||||
|
logging.error("requirements.txt not found. Cannot determine required frontend version.")
|
||||||
|
return None
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error reading requirements.txt: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
def check_frontend_version():
|
def check_frontend_version():
|
||||||
"""Check if the frontend version is up to date."""
|
"""Check if the frontend version is up to date."""
|
||||||
|
|
||||||
def parse_version(version: str) -> tuple[int, int, int]:
|
|
||||||
return tuple(map(int, version.split(".")))
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
frontend_version_str = version("comfyui-frontend-package")
|
frontend_version_str = get_installed_frontend_version()
|
||||||
frontend_version = parse_version(frontend_version_str)
|
frontend_version = parse_version(frontend_version_str)
|
||||||
with open(requirements_path, "r", encoding="utf-8") as f:
|
required_frontend_str = get_required_frontend_version()
|
||||||
required_frontend = parse_version(f.readline().split("=")[-1])
|
required_frontend = parse_version(required_frontend_str)
|
||||||
if frontend_version < required_frontend:
|
if frontend_version < required_frontend:
|
||||||
app.logger.log_startup_warning(
|
app.logger.log_startup_warning(
|
||||||
f"""
|
f"""
|
||||||
@ -168,6 +198,11 @@ def download_release_asset_zip(release: Release, destination_path: str) -> None:
|
|||||||
class FrontendManager:
|
class FrontendManager:
|
||||||
CUSTOM_FRONTENDS_ROOT = str(Path(__file__).parents[1] / "web_custom_versions")
|
CUSTOM_FRONTENDS_ROOT = str(Path(__file__).parents[1] / "web_custom_versions")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_required_frontend_version(cls) -> str:
|
||||||
|
"""Get the required frontend package version."""
|
||||||
|
return get_required_frontend_version()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def default_frontend_path(cls) -> str:
|
def default_frontend_path(cls) -> str:
|
||||||
try:
|
try:
|
||||||
|
|||||||
@ -129,6 +129,11 @@ try:
|
|||||||
except:
|
except:
|
||||||
mlu_available = False
|
mlu_available = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
ixuca_available = hasattr(torch, "corex")
|
||||||
|
except:
|
||||||
|
ixuca_available = False
|
||||||
|
|
||||||
if args.cpu:
|
if args.cpu:
|
||||||
cpu_state = CPUState.CPU
|
cpu_state = CPUState.CPU
|
||||||
|
|
||||||
@ -152,6 +157,12 @@ def is_mlu():
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def is_ixuca():
|
||||||
|
global ixuca_available
|
||||||
|
if ixuca_available:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def get_torch_device():
|
def get_torch_device():
|
||||||
global directml_enabled
|
global directml_enabled
|
||||||
global cpu_state
|
global cpu_state
|
||||||
@ -290,7 +301,7 @@ try:
|
|||||||
if torch_version_numeric[0] >= 2:
|
if torch_version_numeric[0] >= 2:
|
||||||
if ENABLE_PYTORCH_ATTENTION == False and args.use_split_cross_attention == False and args.use_quad_cross_attention == False:
|
if ENABLE_PYTORCH_ATTENTION == False and args.use_split_cross_attention == False and args.use_quad_cross_attention == False:
|
||||||
ENABLE_PYTORCH_ATTENTION = True
|
ENABLE_PYTORCH_ATTENTION = True
|
||||||
if is_intel_xpu() or is_ascend_npu() or is_mlu():
|
if is_intel_xpu() or is_ascend_npu() or is_mlu() or is_ixuca():
|
||||||
if args.use_split_cross_attention == False and args.use_quad_cross_attention == False:
|
if args.use_split_cross_attention == False and args.use_quad_cross_attention == False:
|
||||||
ENABLE_PYTORCH_ATTENTION = True
|
ENABLE_PYTORCH_ATTENTION = True
|
||||||
except:
|
except:
|
||||||
@ -382,6 +393,8 @@ def get_torch_device_name(device):
|
|||||||
except:
|
except:
|
||||||
allocator_backend = ""
|
allocator_backend = ""
|
||||||
return "{} {} : {}".format(device, torch.cuda.get_device_name(device), allocator_backend)
|
return "{} {} : {}".format(device, torch.cuda.get_device_name(device), allocator_backend)
|
||||||
|
elif device.type == "xpu":
|
||||||
|
return "{} {}".format(device, torch.xpu.get_device_name(device))
|
||||||
else:
|
else:
|
||||||
return "{}".format(device.type)
|
return "{}".format(device.type)
|
||||||
elif is_intel_xpu():
|
elif is_intel_xpu():
|
||||||
@ -1046,6 +1059,8 @@ def xformers_enabled():
|
|||||||
return False
|
return False
|
||||||
if is_mlu():
|
if is_mlu():
|
||||||
return False
|
return False
|
||||||
|
if is_ixuca():
|
||||||
|
return False
|
||||||
if directml_enabled:
|
if directml_enabled:
|
||||||
return False
|
return False
|
||||||
return XFORMERS_IS_AVAILABLE
|
return XFORMERS_IS_AVAILABLE
|
||||||
@ -1081,6 +1096,8 @@ def pytorch_attention_flash_attention():
|
|||||||
return True
|
return True
|
||||||
if is_amd():
|
if is_amd():
|
||||||
return True #if you have pytorch attention enabled on AMD it probably supports at least mem efficient attention
|
return True #if you have pytorch attention enabled on AMD it probably supports at least mem efficient attention
|
||||||
|
if is_ixuca():
|
||||||
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def force_upcast_attention_dtype():
|
def force_upcast_attention_dtype():
|
||||||
@ -1206,6 +1223,9 @@ def should_use_fp16(device=None, model_params=0, prioritize_performance=True, ma
|
|||||||
if is_mlu():
|
if is_mlu():
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
if is_ixuca():
|
||||||
|
return True
|
||||||
|
|
||||||
if torch.version.hip:
|
if torch.version.hip:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -1269,6 +1289,9 @@ def should_use_bf16(device=None, model_params=0, prioritize_performance=True, ma
|
|||||||
if is_ascend_npu():
|
if is_ascend_npu():
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
if is_ixuca():
|
||||||
|
return True
|
||||||
|
|
||||||
if is_amd():
|
if is_amd():
|
||||||
arch = torch.cuda.get_device_properties(device).gcnArchName
|
arch = torch.cuda.get_device_properties(device).gcnArchName
|
||||||
if any((a in arch) for a in ["gfx1030", "gfx1031", "gfx1010", "gfx1011", "gfx1012", "gfx906", "gfx900", "gfx803"]): # RDNA2 and older don't support bf16
|
if any((a in arch) for a in ["gfx1030", "gfx1031", "gfx1010", "gfx1011", "gfx1012", "gfx906", "gfx900", "gfx803"]): # RDNA2 and older don't support bf16
|
||||||
|
|||||||
@ -553,6 +553,7 @@ class PromptServer():
|
|||||||
ram_free = comfy.model_management.get_free_memory(cpu_device)
|
ram_free = comfy.model_management.get_free_memory(cpu_device)
|
||||||
vram_total, torch_vram_total = comfy.model_management.get_total_memory(device, torch_total_too=True)
|
vram_total, torch_vram_total = comfy.model_management.get_total_memory(device, torch_total_too=True)
|
||||||
vram_free, torch_vram_free = comfy.model_management.get_free_memory(device, torch_free_too=True)
|
vram_free, torch_vram_free = comfy.model_management.get_free_memory(device, torch_free_too=True)
|
||||||
|
required_frontend_version = FrontendManager.get_required_frontend_version()
|
||||||
|
|
||||||
system_stats = {
|
system_stats = {
|
||||||
"system": {
|
"system": {
|
||||||
@ -560,6 +561,7 @@ class PromptServer():
|
|||||||
"ram_total": ram_total,
|
"ram_total": ram_total,
|
||||||
"ram_free": ram_free,
|
"ram_free": ram_free,
|
||||||
"comfyui_version": __version__,
|
"comfyui_version": __version__,
|
||||||
|
"required_frontend_version": required_frontend_version,
|
||||||
"python_version": sys.version,
|
"python_version": sys.version,
|
||||||
"pytorch_version": comfy.model_management.torch_version,
|
"pytorch_version": comfy.model_management.torch_version,
|
||||||
"embedded_python": os.path.split(os.path.split(sys.executable)[0])[1] == "python_embeded",
|
"embedded_python": os.path.split(os.path.split(sys.executable)[0])[1] == "python_embeded",
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import pytest
|
import pytest
|
||||||
from requests.exceptions import HTTPError
|
from requests.exceptions import HTTPError
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch, mock_open
|
||||||
|
|
||||||
from app.frontend_management import (
|
from app.frontend_management import (
|
||||||
FrontendManager,
|
FrontendManager,
|
||||||
@ -172,3 +172,36 @@ def test_init_frontend_fallback_on_error():
|
|||||||
# Assert
|
# Assert
|
||||||
assert frontend_path == "/default/path"
|
assert frontend_path == "/default/path"
|
||||||
mock_check.assert_called_once()
|
mock_check.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_frontend_version():
|
||||||
|
# Arrange
|
||||||
|
expected_version = "1.25.0"
|
||||||
|
mock_requirements_content = """torch
|
||||||
|
torchsde
|
||||||
|
comfyui-frontend-package==1.25.0
|
||||||
|
other-package==1.0.0
|
||||||
|
numpy"""
|
||||||
|
|
||||||
|
# Act
|
||||||
|
with patch("builtins.open", mock_open(read_data=mock_requirements_content)):
|
||||||
|
version = FrontendManager.get_required_frontend_version()
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
assert version == expected_version
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_frontend_version_invalid_semver():
|
||||||
|
# Arrange
|
||||||
|
mock_requirements_content = """torch
|
||||||
|
torchsde
|
||||||
|
comfyui-frontend-package==1.29.3.75
|
||||||
|
other-package==1.0.0
|
||||||
|
numpy"""
|
||||||
|
|
||||||
|
# Act
|
||||||
|
with patch("builtins.open", mock_open(read_data=mock_requirements_content)):
|
||||||
|
version = FrontendManager.get_required_frontend_version()
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
assert version is None
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user