* [feat] add nodes for z-image * updates for fp4 state dict loading * unit test case for z-image-turbo text-to-image workflow * update documentation templates for z-image * minor fix: remove some warnings and invalid attribute access during model loading * drop down res4lyf test case * style: make linter happy * modify test case metrics * add notes for maintenance * add github url in notes * simplify the notes
167 lines
6.1 KiB
Python
167 lines
6.1 KiB
Python
import logging
|
|
import os
|
|
from pathlib import Path
|
|
|
|
import torch
|
|
import yaml
|
|
from packaging.version import InvalidVersion, Version
|
|
|
|
# vanilla and LTS compatibility snippet
|
|
try:
|
|
from comfy_compatibility.vanilla import prepare_vanilla_environment
|
|
|
|
prepare_vanilla_environment()
|
|
|
|
from comfy.model_downloader import add_known_models
|
|
from comfy.model_downloader_types import HuggingFile
|
|
|
|
capability = torch.cuda.get_device_capability(0 if torch.cuda.is_available() else None)
|
|
sm = f"{capability[0]}{capability[1]}"
|
|
precision = "fp4" if sm == "120" else "int4"
|
|
|
|
# add known models
|
|
|
|
models_yaml_path = Path(__file__).parent / "test_data" / "models.yaml"
|
|
with open(models_yaml_path, "r") as f:
|
|
nunchaku_models_yaml = yaml.safe_load(f)
|
|
|
|
NUNCHAKU_SVDQ_MODELS = []
|
|
for model in nunchaku_models_yaml["models"]:
|
|
filename = model["filename"]
|
|
if not filename.startswith("svdq-"):
|
|
continue
|
|
if "{precision}" in filename:
|
|
filename = filename.format(precision=precision)
|
|
NUNCHAKU_SVDQ_MODELS.append(HuggingFile(repo_id=model["repo_id"], filename=filename))
|
|
|
|
NUNCHAKU_SVDQ_TEXT_ENCODER_MODELS = [
|
|
HuggingFile(repo_id="nunchaku-tech/nunchaku-t5", filename="awq-int4-flux.1-t5xxl.safetensors"),
|
|
]
|
|
|
|
add_known_models("diffusion_models", *NUNCHAKU_SVDQ_MODELS)
|
|
add_known_models("text_encoders", *NUNCHAKU_SVDQ_TEXT_ENCODER_MODELS)
|
|
except (ImportError, ModuleNotFoundError):
|
|
pass
|
|
|
|
# Get log level from environment variable (default to INFO)
|
|
log_level = os.getenv("LOG_LEVEL", "INFO").upper()
|
|
|
|
# Configure logging
|
|
logging.basicConfig(level=getattr(logging, log_level, logging.INFO), format="%(asctime)s - %(levelname)s - %(message)s")
|
|
logger = logging.getLogger(__name__)
|
|
|
|
logger.info("=" * 40 + " ComfyUI-nunchaku Initialization " + "=" * 40)
|
|
|
|
from .utils import get_package_version, get_plugin_version
|
|
|
|
nunchaku_full_version = get_package_version("nunchaku").split("+")[0].strip()
|
|
|
|
logger.info(f"Nunchaku version: {nunchaku_full_version}")
|
|
logger.info(f"ComfyUI-nunchaku version: {get_plugin_version()}")
|
|
|
|
|
|
min_nunchaku_version = "1.0.0"
|
|
nunchaku_version = nunchaku_full_version.split("+")[0].strip()
|
|
nunchaku_major_minor_patch_version = ".".join(nunchaku_version.split(".")[:3])
|
|
|
|
try:
|
|
if Version(nunchaku_major_minor_patch_version) < Version(min_nunchaku_version):
|
|
logger.warning(
|
|
f"ComfyUI-nunchaku {get_plugin_version()} requires nunchaku >= v{min_nunchaku_version}, "
|
|
f"but found nunchaku {nunchaku_full_version}. Please update nunchaku."
|
|
)
|
|
except InvalidVersion:
|
|
logger.warning(
|
|
f"Could not parse nunchaku version: {nunchaku_full_version}. "
|
|
f"Please ensure you have at least v{min_nunchaku_version}."
|
|
)
|
|
|
|
NODE_CLASS_MAPPINGS = {}
|
|
|
|
try:
|
|
from .nodes.models.flux import NunchakuFluxDiTLoader
|
|
|
|
NODE_CLASS_MAPPINGS["NunchakuFluxDiTLoader"] = NunchakuFluxDiTLoader
|
|
except ImportError:
|
|
logger.exception("Node `NunchakuFluxDiTLoader` import failed:")
|
|
|
|
try:
|
|
from .nodes.models.qwenimage import NunchakuQwenImageDiTLoader
|
|
|
|
NODE_CLASS_MAPPINGS["NunchakuQwenImageDiTLoader"] = NunchakuQwenImageDiTLoader
|
|
except ImportError:
|
|
logger.exception("Node `NunchakuQwenImageDiTLoader` import failed:")
|
|
|
|
try:
|
|
from .nodes.lora.flux import NunchakuFluxLoraLoader, NunchakuFluxLoraStack
|
|
|
|
NODE_CLASS_MAPPINGS["NunchakuFluxLoraLoader"] = NunchakuFluxLoraLoader
|
|
NODE_CLASS_MAPPINGS["NunchakuFluxLoraStack"] = NunchakuFluxLoraStack
|
|
except ImportError:
|
|
logger.exception("Nodes `NunchakuFluxLoraLoader` and `NunchakuFluxLoraStack` import failed:")
|
|
|
|
try:
|
|
from .nodes.models.text_encoder import NunchakuTextEncoderLoader, NunchakuTextEncoderLoaderV2
|
|
|
|
NODE_CLASS_MAPPINGS["NunchakuTextEncoderLoader"] = NunchakuTextEncoderLoader
|
|
NODE_CLASS_MAPPINGS["NunchakuTextEncoderLoaderV2"] = NunchakuTextEncoderLoaderV2
|
|
except ImportError:
|
|
logger.exception("Nodes `NunchakuTextEncoderLoader` and `NunchakuTextEncoderLoaderV2` import failed:")
|
|
|
|
try:
|
|
from .nodes.preprocessors.depth import FluxDepthPreprocessor
|
|
|
|
NODE_CLASS_MAPPINGS["NunchakuDepthPreprocessor"] = FluxDepthPreprocessor
|
|
except ImportError:
|
|
logger.exception("Node `NunchakuDepthPreprocessor` import failed:")
|
|
|
|
try:
|
|
from .nodes.models.pulid import (
|
|
NunchakuFluxPuLIDApplyV2,
|
|
NunchakuPulidApply,
|
|
NunchakuPulidLoader,
|
|
NunchakuPuLIDLoaderV2,
|
|
)
|
|
|
|
NODE_CLASS_MAPPINGS["NunchakuPulidApply"] = NunchakuPulidApply
|
|
NODE_CLASS_MAPPINGS["NunchakuPulidLoader"] = NunchakuPulidLoader
|
|
NODE_CLASS_MAPPINGS["NunchakuPuLIDLoaderV2"] = NunchakuPuLIDLoaderV2
|
|
NODE_CLASS_MAPPINGS["NunchakuFluxPuLIDApplyV2"] = NunchakuFluxPuLIDApplyV2
|
|
except ImportError:
|
|
logger.exception(
|
|
"Nodes `NunchakuPulidApply`,`NunchakuPulidLoader`, "
|
|
"`NunchakuPuLIDLoaderV2` and `NunchakuFluxPuLIDApplyV2` import failed:"
|
|
)
|
|
try:
|
|
from .nodes.models.ipadapter import NunchakuFluxIPAdapterApply, NunchakuIPAdapterLoader
|
|
|
|
NODE_CLASS_MAPPINGS["NunchakuFluxIPAdapterApply"] = NunchakuFluxIPAdapterApply
|
|
NODE_CLASS_MAPPINGS["NunchakuIPAdapterLoader"] = NunchakuIPAdapterLoader
|
|
except ImportError:
|
|
logger.exception("Nodes `NunchakuFluxIPAdapterApply` and `NunchakuIPAdapterLoader` import failed:")
|
|
|
|
try:
|
|
from .nodes.models.zimage import NunchakuZImageDiTLoader
|
|
|
|
NODE_CLASS_MAPPINGS["NunchakuZImageDiTLoader"] = NunchakuZImageDiTLoader
|
|
except ImportError:
|
|
logger.exception("Nodes `NunchakuZImageDiTLoader` import failed:")
|
|
|
|
try:
|
|
from .nodes.tools.merge_safetensors import NunchakuModelMerger
|
|
|
|
NODE_CLASS_MAPPINGS["NunchakuModelMerger"] = NunchakuModelMerger
|
|
except ImportError:
|
|
logger.exception("Node `NunchakuModelMerger` import failed:")
|
|
|
|
try:
|
|
from .nodes.tools.installers import NunchakuWheelInstaller
|
|
|
|
NODE_CLASS_MAPPINGS["NunchakuWheelInstaller"] = NunchakuWheelInstaller
|
|
except ImportError:
|
|
logger.exception("Node `NunchakuWheelInstaller` import failed:")
|
|
|
|
NODE_DISPLAY_NAME_MAPPINGS = {k: v.TITLE for k, v in NODE_CLASS_MAPPINGS.items()}
|
|
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"]
|
|
logger.info("=" * (80 + len(" ComfyUI-nunchaku Initialization ")))
|