254 lines
7.6 KiB
Python
Executable File
254 lines
7.6 KiB
Python
Executable File
import os
|
|
import comfy
|
|
import torch
|
|
import sys
|
|
import folder_paths
|
|
import numpy
|
|
import pygit2
|
|
import hashlib
|
|
from PIL import Image
|
|
|
|
this_path = os.path.dirname(__file__)
|
|
repo_dir = os.path.join(this_path, "InfiniteYou")
|
|
requirements_txt = os.path.join(repo_dir, "requirements.txt")
|
|
|
|
if not os.path.exists(requirements_txt):
|
|
pygit2.clone_repository(
|
|
"https://github.com/bytedance/InfiniteYou",
|
|
repo_dir,
|
|
depth=1
|
|
)
|
|
if not os.path.exists(requirements_txt):
|
|
print("*** Could not get InfiniteYou repository. Please install git.")
|
|
|
|
sys.path.insert(0, this_path)
|
|
from InfiniteYou.pipelines.pipeline_infu_flux import ( # noqa: E402
|
|
InfUFluxPipeline
|
|
)
|
|
sys.path.remove(this_path)
|
|
|
|
|
|
class InfiniteYouSampler:
|
|
def __init__(self):
|
|
pass
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(s):
|
|
base_models = (
|
|
['auto'] +
|
|
folder_paths.get_filename_list("diffusion_models")
|
|
)
|
|
return {
|
|
"required": {
|
|
"id_image": ("IMAGE",),
|
|
"base_model": (base_models, ),
|
|
"seed": ("INT", {
|
|
"default": 0
|
|
}),
|
|
"prompt": ("STRING", {
|
|
"multiline": True,
|
|
"default": "a man on a horse",
|
|
"lazy": True
|
|
}),
|
|
"steps": ("INT", {
|
|
"default": 30
|
|
}),
|
|
},
|
|
"optional": {
|
|
"guidance": ("FLOAT", {
|
|
"default": 3.5,
|
|
"min": 0.0,
|
|
"step": 0.1,
|
|
"round": 0.01,
|
|
"display": "number",
|
|
"lazy": True
|
|
}),
|
|
"infusenet_conditioning_scale": ("FLOAT", {
|
|
"default": 1.0,
|
|
"min": 0.0,
|
|
"step": 0.1,
|
|
"round": 0.01,
|
|
"display": "number",
|
|
"lazy": True
|
|
}),
|
|
"infusenet_guidance_start": ("FLOAT", {
|
|
"default": 0.0,
|
|
"min": 0.0,
|
|
"step": 0.1,
|
|
"round": 0.01,
|
|
"display": "number",
|
|
"lazy": True
|
|
}),
|
|
"infusenet_guidance_end": ("FLOAT", {
|
|
"default": 1.0,
|
|
"min": 0.0,
|
|
"step": 0.1,
|
|
"round": 0.01,
|
|
"display": "number",
|
|
"lazy": True
|
|
}),
|
|
"model_version": (['aes_stage2', 'sim_stage1'], {
|
|
"default": 'aes_stage2'
|
|
}),
|
|
"control_image": ("IMAGE",),
|
|
"width": ("INT", {
|
|
"default": 864,
|
|
}),
|
|
"height": ("INT", {
|
|
"default": 1152,
|
|
}),
|
|
"enable_realism": ("BOOLEAN", {
|
|
"default": False
|
|
}),
|
|
"enable_anti_blur": ("BOOLEAN", {
|
|
"default": False
|
|
}),
|
|
"quantize_8bit": ("BOOLEAN", {
|
|
"default": True
|
|
}),
|
|
},
|
|
}
|
|
|
|
RETURN_TYPES = ("IMAGE",)
|
|
|
|
FUNCTION = "sampler"
|
|
CATEGORY = "sampling"
|
|
|
|
def sampler(
|
|
self,
|
|
id_image,
|
|
base_model,
|
|
seed,
|
|
prompt,
|
|
steps=30,
|
|
guidance=3.5,
|
|
infusenet_conditioning_scale=1.0,
|
|
infusenet_guidance_start=0.0,
|
|
infusenet_guidance_end=1.0,
|
|
model_version='aes_stage2',
|
|
control_image=None,
|
|
width=864,
|
|
height=1152,
|
|
enable_realism=False,
|
|
enable_anti_blur=False,
|
|
quantize_8bit=True,
|
|
):
|
|
# torch.cuda.set_device(comfy.model_management.get_torch_device())
|
|
|
|
infu_flux_version = 'v1.0'
|
|
model_dir = 'ByteDance/InfiniteYou'
|
|
if base_model == 'auto':
|
|
base_model_path = 'black-forest-labs/FLUX.1-dev'
|
|
else:
|
|
# TODO
|
|
base_model_path = folder_paths.get_full_path_or_raise(
|
|
"diffusion_models", base_model
|
|
)
|
|
|
|
infu_model_path = os.path.join(
|
|
model_dir, f'infu_flux_{infu_flux_version}',
|
|
model_version
|
|
)
|
|
insightface_root_path = os.path.join(
|
|
model_dir, 'supports', 'insightface'
|
|
)
|
|
pipe = InfUFluxPipeline(
|
|
base_model_path=base_model_path,
|
|
infu_model_path=infu_model_path,
|
|
insightface_root_path=insightface_root_path,
|
|
infu_flux_version=infu_flux_version,
|
|
model_version=model_version,
|
|
quantize_8bit=quantize_8bit,
|
|
)
|
|
|
|
|
|
lora_dir = os.path.join(model_dir, 'supports', 'optional_loras')
|
|
if not os.path.exists(lora_dir):
|
|
lora_dir = "./models/InfiniteYou/supports/optional_loras"
|
|
|
|
loras = []
|
|
if enable_realism:
|
|
loras.append([os.path.join(lora_dir, 'flux_realism_lora.safetensors'), 'realism', 1.0])
|
|
if enable_anti_blur:
|
|
loras.append([os.path.join(lora_dir, 'flux_anti_blur_lora.safetensors'), 'anti_blur', 1.0])
|
|
if loras:
|
|
pipe.load_loras(loras)
|
|
|
|
images = []
|
|
i_upto = 0
|
|
for id_image in id_image:
|
|
control_image_pil = None
|
|
if control_image is not None:
|
|
c_upto = i_upto % len(control_image)
|
|
control_i = 255. * control_image[c_upto].cpu().numpy()
|
|
control_image_pil = Image.fromarray(
|
|
numpy.clip(control_i, 0, 255).astype(numpy.uint8)
|
|
)
|
|
|
|
i = 255. * id_image.cpu().numpy()
|
|
img = Image.fromarray(numpy.clip(i, 0, 255).astype(numpy.uint8))
|
|
image = pipe(
|
|
id_image=img,
|
|
prompt=prompt,
|
|
control_image=control_image_pil,
|
|
seed=seed,
|
|
guidance_scale=guidance,
|
|
num_steps=steps,
|
|
infusenet_conditioning_scale=infusenet_conditioning_scale,
|
|
infusenet_guidance_start=infusenet_guidance_start,
|
|
infusenet_guidance_end=infusenet_guidance_end,
|
|
width=width,
|
|
height=height,
|
|
)
|
|
image = image.convert("RGB")
|
|
image = numpy.array(image).astype(numpy.float32) / 255.0
|
|
image = torch.from_numpy(image)[None,]
|
|
images.append(image)
|
|
i_upto += 1
|
|
|
|
if len(images) > 1:
|
|
images = torch.cat(images, dim=0)
|
|
else:
|
|
images = images[0]
|
|
|
|
return (images,)
|
|
|
|
@classmethod
|
|
def IS_CHANGED(
|
|
self,
|
|
id_image,
|
|
base_model,
|
|
seed,
|
|
prompt,
|
|
steps,
|
|
guidance,
|
|
infusenet_conditioning_scale,
|
|
infusenet_guidance_start,
|
|
infusenet_guidance_end,
|
|
model_version,
|
|
control_image,
|
|
width,
|
|
height,
|
|
enable_realism,
|
|
enable_anti_blur,
|
|
quantize_8bit,
|
|
):
|
|
m = hashlib.sha256()
|
|
m.update(id_image)
|
|
m.update(base_model)
|
|
m.update(seed)
|
|
m.update(prompt)
|
|
m.update(steps)
|
|
m.update(guidance)
|
|
m.update(infusenet_conditioning_scale)
|
|
m.update(infusenet_guidance_start)
|
|
m.update(infusenet_guidance_end)
|
|
m.update(model_version)
|
|
m.update(control_image)
|
|
m.update(width)
|
|
m.update(height)
|
|
m.update(enable_realism)
|
|
m.update(enable_anti_blur)
|
|
m.update(quantize_8bit)
|
|
return m.digest().hex()
|