Use ComfyUI Krea2 component loaders
Browse files
app.py
CHANGED
|
@@ -17,6 +17,9 @@ from PIL import Image
|
|
| 17 |
|
| 18 |
MODEL_REPO = "Daankular/redcraft-krea2-fp8"
|
| 19 |
MODEL_FILE = "redcraftKREA2RedMix_krea2Edition.safetensors"
|
|
|
|
|
|
|
|
|
|
| 20 |
COMFY_REPO = "https://github.com/comfyanonymous/ComfyUI.git"
|
| 21 |
COMFY_DIR = Path(os.environ.get("COMFYUI_DIR", "/tmp/ComfyUI"))
|
| 22 |
COMFY_HOST = "127.0.0.1"
|
|
@@ -51,15 +54,20 @@ def _validate_comfyui():
|
|
| 51 |
response = requests.get(f"{COMFY_URL}/object_info", timeout=30)
|
| 52 |
response.raise_for_status()
|
| 53 |
object_info = response.json()
|
| 54 |
-
required_nodes = ["
|
| 55 |
missing = [node for node in required_nodes if node not in object_info]
|
| 56 |
if missing:
|
| 57 |
raise RuntimeError(f"ComfyUI is missing required nodes: {', '.join(missing)}")
|
| 58 |
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
|
| 64 |
|
| 65 |
def _ensure_comfyui():
|
|
@@ -83,12 +91,28 @@ def _ensure_comfyui():
|
|
| 83 |
_run([sys.executable, "-m", "pip", "install", "-r", "requirements.txt"], cwd=COMFY_DIR)
|
| 84 |
marker.write_text("ok", encoding="utf-8")
|
| 85 |
|
| 86 |
-
|
| 87 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
hf_hub_download(
|
| 89 |
repo_id=MODEL_REPO,
|
| 90 |
filename=MODEL_FILE,
|
| 91 |
-
local_dir=str(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
token=os.environ.get("HF_TOKEN"),
|
| 93 |
)
|
| 94 |
|
|
@@ -124,12 +148,20 @@ def _start_comfyui():
|
|
| 124 |
def _build_workflow(prompt, negative_prompt, width, height, steps, cfg, seed, sampler, scheduler):
|
| 125 |
workflow = {
|
| 126 |
"1": {
|
| 127 |
-
"class_type": "
|
| 128 |
-
"inputs": {"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
},
|
| 130 |
"2": {
|
| 131 |
"class_type": "CLIPTextEncode",
|
| 132 |
-
"inputs": {"text": prompt, "clip": ["
|
| 133 |
},
|
| 134 |
"4": {
|
| 135 |
"class_type": "EmptyLatentImage",
|
|
@@ -152,7 +184,7 @@ def _build_workflow(prompt, negative_prompt, width, height, steps, cfg, seed, sa
|
|
| 152 |
},
|
| 153 |
"6": {
|
| 154 |
"class_type": "VAEDecode",
|
| 155 |
-
"inputs": {"samples": ["5", 0], "vae": ["
|
| 156 |
},
|
| 157 |
"7": {
|
| 158 |
"class_type": "SaveImage",
|
|
@@ -163,7 +195,7 @@ def _build_workflow(prompt, negative_prompt, width, height, steps, cfg, seed, sa
|
|
| 163 |
if negative_prompt and negative_prompt.strip():
|
| 164 |
workflow["3"] = {
|
| 165 |
"class_type": "CLIPTextEncode",
|
| 166 |
-
"inputs": {"text": negative_prompt, "clip": ["
|
| 167 |
}
|
| 168 |
else:
|
| 169 |
workflow["3"] = {
|
|
|
|
| 17 |
|
| 18 |
MODEL_REPO = "Daankular/redcraft-krea2-fp8"
|
| 19 |
MODEL_FILE = "redcraftKREA2RedMix_krea2Edition.safetensors"
|
| 20 |
+
COMFY_KREA_REPO = "Comfy-Org/Krea-2"
|
| 21 |
+
TEXT_ENCODER_FILE = "qwen3vl_4b_bf16.safetensors"
|
| 22 |
+
VAE_FILE = "qwen_image_vae.safetensors"
|
| 23 |
COMFY_REPO = "https://github.com/comfyanonymous/ComfyUI.git"
|
| 24 |
COMFY_DIR = Path(os.environ.get("COMFYUI_DIR", "/tmp/ComfyUI"))
|
| 25 |
COMFY_HOST = "127.0.0.1"
|
|
|
|
| 54 |
response = requests.get(f"{COMFY_URL}/object_info", timeout=30)
|
| 55 |
response.raise_for_status()
|
| 56 |
object_info = response.json()
|
| 57 |
+
required_nodes = ["UNETLoader", "CLIPLoader", "VAELoader", "CLIPTextEncode", "KSampler", "VAEDecode", "SaveImage"]
|
| 58 |
missing = [node for node in required_nodes if node not in object_info]
|
| 59 |
if missing:
|
| 60 |
raise RuntimeError(f"ComfyUI is missing required nodes: {', '.join(missing)}")
|
| 61 |
|
| 62 |
+
unet_info = object_info["UNETLoader"]["input"]["required"]["unet_name"][0]
|
| 63 |
+
clip_info = object_info["CLIPLoader"]["input"]["required"]["clip_name"][0]
|
| 64 |
+
vae_info = object_info["VAELoader"]["input"]["required"]["vae_name"][0]
|
| 65 |
+
if MODEL_FILE not in unet_info:
|
| 66 |
+
raise RuntimeError(f"Redcraft diffusion model is not visible to ComfyUI. First models: {', '.join(unet_info[:10])}")
|
| 67 |
+
if TEXT_ENCODER_FILE not in clip_info:
|
| 68 |
+
raise RuntimeError(f"Krea2 text encoder is not visible to ComfyUI. First encoders: {', '.join(clip_info[:10])}")
|
| 69 |
+
if VAE_FILE not in vae_info:
|
| 70 |
+
raise RuntimeError(f"Krea2 VAE is not visible to ComfyUI. First VAEs: {', '.join(vae_info[:10])}")
|
| 71 |
|
| 72 |
|
| 73 |
def _ensure_comfyui():
|
|
|
|
| 91 |
_run([sys.executable, "-m", "pip", "install", "-r", "requirements.txt"], cwd=COMFY_DIR)
|
| 92 |
marker.write_text("ok", encoding="utf-8")
|
| 93 |
|
| 94 |
+
diffusion_dir = COMFY_DIR / "models" / "diffusion_models"
|
| 95 |
+
text_encoder_dir = COMFY_DIR / "models" / "text_encoders"
|
| 96 |
+
vae_dir = COMFY_DIR / "models" / "vae"
|
| 97 |
+
diffusion_dir.mkdir(parents=True, exist_ok=True)
|
| 98 |
+
text_encoder_dir.mkdir(parents=True, exist_ok=True)
|
| 99 |
+
vae_dir.mkdir(parents=True, exist_ok=True)
|
| 100 |
hf_hub_download(
|
| 101 |
repo_id=MODEL_REPO,
|
| 102 |
filename=MODEL_FILE,
|
| 103 |
+
local_dir=str(diffusion_dir),
|
| 104 |
+
token=os.environ.get("HF_TOKEN"),
|
| 105 |
+
)
|
| 106 |
+
hf_hub_download(
|
| 107 |
+
repo_id=COMFY_KREA_REPO,
|
| 108 |
+
filename=f"text_encoders/{TEXT_ENCODER_FILE}",
|
| 109 |
+
local_dir=str(COMFY_DIR / "models"),
|
| 110 |
+
token=os.environ.get("HF_TOKEN"),
|
| 111 |
+
)
|
| 112 |
+
hf_hub_download(
|
| 113 |
+
repo_id=COMFY_KREA_REPO,
|
| 114 |
+
filename=f"vae/{VAE_FILE}",
|
| 115 |
+
local_dir=str(COMFY_DIR / "models"),
|
| 116 |
token=os.environ.get("HF_TOKEN"),
|
| 117 |
)
|
| 118 |
|
|
|
|
| 148 |
def _build_workflow(prompt, negative_prompt, width, height, steps, cfg, seed, sampler, scheduler):
|
| 149 |
workflow = {
|
| 150 |
"1": {
|
| 151 |
+
"class_type": "UNETLoader",
|
| 152 |
+
"inputs": {"unet_name": MODEL_FILE, "weight_dtype": "default"},
|
| 153 |
+
},
|
| 154 |
+
"8": {
|
| 155 |
+
"class_type": "CLIPLoader",
|
| 156 |
+
"inputs": {"clip_name": TEXT_ENCODER_FILE, "type": "krea2", "device": "default"},
|
| 157 |
+
},
|
| 158 |
+
"9": {
|
| 159 |
+
"class_type": "VAELoader",
|
| 160 |
+
"inputs": {"vae_name": VAE_FILE},
|
| 161 |
},
|
| 162 |
"2": {
|
| 163 |
"class_type": "CLIPTextEncode",
|
| 164 |
+
"inputs": {"text": prompt, "clip": ["8", 0]},
|
| 165 |
},
|
| 166 |
"4": {
|
| 167 |
"class_type": "EmptyLatentImage",
|
|
|
|
| 184 |
},
|
| 185 |
"6": {
|
| 186 |
"class_type": "VAEDecode",
|
| 187 |
+
"inputs": {"samples": ["5", 0], "vae": ["9", 0]},
|
| 188 |
},
|
| 189 |
"7": {
|
| 190 |
"class_type": "SaveImage",
|
|
|
|
| 195 |
if negative_prompt and negative_prompt.strip():
|
| 196 |
workflow["3"] = {
|
| 197 |
"class_type": "CLIPTextEncode",
|
| 198 |
+
"inputs": {"text": negative_prompt, "clip": ["8", 0]},
|
| 199 |
}
|
| 200 |
else:
|
| 201 |
workflow["3"] = {
|