8.0 KiB
8.0 KiB
Documentation
- Class name: SUPIR_model_loader
- Category: SUPIR
- Output node: False
SUPIR_model_loader节点负责加载SUPIR模型,这是SUPIR框架中用于图像处理和增强的关键组件。它处理模型的初始化和配置,确保模型为后续的图像处理任务做好准备。
Input types
Required
- supir_model
- 指定SUPIR模型checkpoint文件的路径,对于加载模型的状态以进行图像处理任务至关重要。
- Comfy dtype: COMBO[STRING]
- Python dtype: List[str]
- sdxl_model
- 指定SDXL模型checkpoint文件的路径,这些文件将与SUPIR模型合并以增强其功能。
- Comfy dtype: COMBO[STRING]
- Python dtype: List[str]
- fp8_unet
- 一个标志,用于确定是否将UNet权重转换为较低精度格式以节省VRAM,这可能会对质量产生轻微影响。
- Comfy dtype: BOOLEAN
- Python dtype: bool
- diffusion_dtype
- 指定扩散操作的数据类型,提供了优化性能或兼容性的选项。
- Comfy dtype: COMBO[STRING]
- Python dtype: str
Output types
- SUPIR_model
- 加载和配置完毕的SUPIR模型,可以立即用于图像处理任务。
- Comfy dtype: SUPIRMODEL
- Python dtype: torch.nn.Module
- SUPIR_VAE
- SUPIR模型的VAE组件,对某些图像处理操作至关重要。
- Comfy dtype: SUPIRVAE
- Python dtype: torch.nn.Module
Usage tips
- Infra type:
CPU - Common nodes: unknown
Source code
class SUPIR_model_loader:
@classmethod
def INPUT_TYPES(s):
return {"required": {
"supir_model": (folder_paths.get_filename_list("checkpoints"),),
"sdxl_model": (folder_paths.get_filename_list("checkpoints"),),
"fp8_unet": ("BOOLEAN", {"default": False}),
"diffusion_dtype": (
[
'fp16',
'bf16',
'fp32',
'auto'
], {
"default": 'auto'
}),
},
}
RETURN_TYPES = ("SUPIRMODEL", "SUPIRVAE")
RETURN_NAMES = ("SUPIR_model","SUPIR_VAE",)
FUNCTION = "process"
CATEGORY = "SUPIR"
DESCRIPTION = """
Old loader, not recommended to be used.
Loads the SUPIR model and the selected SDXL model and merges them.
"""
def process(self, supir_model, sdxl_model, diffusion_dtype, fp8_unet):
device = mm.get_torch_device()
mm.unload_all_models()
SUPIR_MODEL_PATH = folder_paths.get_full_path("checkpoints", supir_model)
SDXL_MODEL_PATH = folder_paths.get_full_path("checkpoints", sdxl_model)
config_path = os.path.join(script_directory, "options/SUPIR_v0.yaml")
clip_config_path = os.path.join(script_directory, "configs/clip_vit_config.json")
tokenizer_path = os.path.join(script_directory, "configs/tokenizer")
custom_config = {
'sdxl_model': sdxl_model,
'diffusion_dtype': diffusion_dtype,
'supir_model': supir_model,
'fp8_unet': fp8_unet,
}
if diffusion_dtype == 'auto':
try:
if mm.should_use_fp16():
print("Diffusion using fp16")
dtype = torch.float16
model_dtype = 'fp16'
elif mm.should_use_bf16():
print("Diffusion using bf16")
dtype = torch.bfloat16
model_dtype = 'bf16'
else:
print("Diffusion using fp32")
dtype = torch.float32
model_dtype = 'fp32'
except:
raise AttributeError("ComfyUI version too old, can't autodetect properly. Set your dtypes manually.")
else:
print(f"Diffusion using {diffusion_dtype}")
dtype = convert_dtype(diffusion_dtype)
model_dtype = diffusion_dtype
if not hasattr(self, "model") or self.model is None or self.current_config != custom_config:
self.current_config = custom_config
self.model = None
mm.soft_empty_cache()
config = OmegaConf.load(config_path)
if mm.XFORMERS_IS_AVAILABLE:
print("Using XFORMERS")
config.model.params.control_stage_config.params.spatial_transformer_attn_type = "softmax-xformers"
config.model.params.network_config.params.spatial_transformer_attn_type = "softmax-xformers"
config.model.params.first_stage_config.params.ddconfig.attn_type = "vanilla-xformers"
config.model.params.diffusion_dtype = model_dtype
config.model.target = ".SUPIR.models.SUPIR_model_v2.SUPIRModel"
pbar = comfy.utils.ProgressBar(5)
self.model = instantiate_from_config(config.model).cpu()
self.model.model.dtype = dtype
pbar.update(1)
try:
print(f"Attempting to load SDXL model: [{SDXL_MODEL_PATH}]")
sdxl_state_dict = load_state_dict(SDXL_MODEL_PATH)
self.model.load_state_dict(sdxl_state_dict, strict=False)
if fp8_unet:
self.model.model.to(torch.float8_e4m3fn)
else:
self.model.model.to(dtype)
pbar.update(1)
except:
raise Exception("Failed to load SDXL model")
#first clip model from SDXL checkpoint
try:
print("Loading first clip model from SDXL checkpoint")
replace_prefix = {}
replace_prefix["conditioner.embedders.0.transformer."] = ""
sd = comfy.utils.state_dict_prefix_replace(sdxl_state_dict, replace_prefix, filter_keys=False)
clip_text_config = CLIPTextConfig.from_pretrained(clip_config_path)
self.model.conditioner.embedders[0].tokenizer = CLIPTokenizer.from_pretrained(tokenizer_path)
self.model.conditioner.embedders[0].transformer = CLIPTextModel(clip_text_config)
self.model.conditioner.embedders[0].transformer.load_state_dict(sd, strict=False)
self.model.conditioner.embedders[0].eval()
self.model.conditioner.embedders[0].to(dtype)
for param in self.model.conditioner.embedders[0].parameters():
param.requires_grad = False
pbar.update(1)
except:
raise Exception("Failed to load first clip model from SDXL checkpoint")
del sdxl_state_dict
#second clip model from SDXL checkpoint
try:
print("Loading second clip model from SDXL checkpoint")
replace_prefix2 = {}
replace_prefix2["conditioner.embedders.1.model."] = ""
sd = comfy.utils.state_dict_prefix_replace(sd, replace_prefix2, filter_keys=True)
clip_g = build_text_model_from_openai_state_dict(sd, device, cast_dtype=dtype)
self.model.conditioner.embedders[1].model = clip_g
self.model.conditioner.embedders[1].to(dtype)
pbar.update(1)
except:
raise Exception("Failed to load second clip model from SDXL checkpoint")
del sd, clip_g
try:
print(f'Attempting to load SUPIR model: [{SUPIR_MODEL_PATH}]')
supir_state_dict = load_state_dict(SUPIR_MODEL_PATH)
self.model.load_state_dict(supir_state_dict, strict=False)
if fp8_unet:
self.model.model.to(torch.float8_e4m3fn)
else:
self.model.model.to(dtype)
del supir_state_dict
pbar.update(1)
except:
raise Exception("Failed to load SUPIR model")
mm.soft_empty_cache()
return (self.model, self.model.first_stage_model,)