Spaces:
Sleeping
Sleeping
File size: 6,288 Bytes
c24f7c5 a29d7ef 12eaa16 c24f7c5 12eaa16 c24f7c5 12eaa16 c24f7c5 a29d7ef aa3776e 526f8c3 12eaa16 aa3776e 526f8c3 aa3776e 526f8c3 12eaa16 526f8c3 12eaa16 526f8c3 6a078c5 6275165 6a078c5 a29d7ef aa3776e 12eaa16 a49802e 6a078c5 dffb4a8 95c986b 6a078c5 6275165 dffb4a8 6a078c5 a29d7ef 6a078c5 a29d7ef 46fdc1c c24f7c5 a29d7ef aa3776e c62ade5 a29d7ef c24f7c5 dffb4a8 6275165 c24f7c5 6a078c5 aa3776e 6a078c5 aa3776e dffb4a8 aa3776e 6a078c5 aa3776e 12eaa16 ff46616 12eaa16 aa3776e 12eaa16 aa3776e ff46616 6a078c5 aa3776e 6a078c5 12eaa16 6a078c5 aa3776e a29d7ef 6a078c5 a29d7ef c24f7c5 aa3776e c24f7c5 dffb4a8 c24f7c5 a29d7ef c24f7c5 a29d7ef | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | import os
import sys
import subprocess
import time
import json
import urllib.request
import urllib.parse
import gradio as gr
import torch
import spaces
# ==========================================
# 1. Install Dependencies Natively at Startup
# ==========================================
required_packages = [
"safetensors", "scipy", "tqdm", "psutil", "einops",
"transformers", "tokenizers", "sentencepiece", "torchsde",
"huggingface-hub", "aiohttp", "yarl", "av", "blake3",
"sqlalchemy", "alembic", "comfy-aimdo"
]
print("Checking system requirements...")
for package in required_packages:
try:
__import__(package.replace("-", "_"))
except ImportError:
print(f"Installing missing dependency: {package}")
subprocess.run([sys.executable, "-m", "pip", "install", package], check=True)
# ==========================================
# 2. Clone ComfyUI & Download Custom Model
# ==========================================
COMFYUI_DIR = os.path.abspath("ComfyUI")
if not os.path.exists(COMFYUI_DIR):
print("Cloning ComfyUI framework...")
subprocess.run(["git", "clone", "https://github.com/comfyanonymous/ComfyUI.git", COMFYUI_DIR], check=True)
# Ensure the models directory exists
CHECKPOINT_DIR = os.path.join(COMFYUI_DIR, "models", "checkpoints")
os.makedirs(CHECKPOINT_DIR, exist_ok=True)
# Download the exact model your workflow requires
model_filename = "epicphotogasm_ultimateFidelity.safetensors"
model_path = os.path.join(CHECKPOINT_DIR, model_filename)
if not os.path.exists(model_path):
print(f"Downloading {model_filename} (This may take a few minutes)...")
# Public HuggingFace mirror for the EpicPhotogasm checkpoint
model_url = "https://huggingface.co/sibylexpe/ModelsSD15/resolve/main/epicphotogasm_ultimateFidelity.safetensors"
subprocess.run(["wget", "-q", "-O", model_path, model_url], check=True)
# ==========================================
# 3. Dynamic GPU Inference Function
# ==========================================
# FIX: Capitalized GPU here
@spaces.GPU(duration=120)
def generate_image(user_prompt):
if not os.path.exists("workflow_api.json"):
print("Error: workflow_api.json missing from root directory.")
return None
with open("workflow_api.json", "r") as f:
prompt_workflow = json.load(f)
# Automatically patch the SD3 vs SD 1.5 Latent Mismatch
if "68" in prompt_workflow and prompt_workflow["68"].get("class_type") == "EmptySD3LatentImage":
prompt_workflow["68"]["class_type"] = "EmptyLatentImage"
# Inject your prompt into the correct CLIP Text Encode node ID (67)
if "67" in prompt_workflow and "inputs" in prompt_workflow["67"]:
prompt_workflow["67"]["inputs"]["text"] = user_prompt
# Clear old remnants in both output and temp directories
search_dirs = [os.path.join(COMFYUI_DIR, "output"), os.path.join(COMFYUI_DIR, "temp")]
for d in search_dirs:
if os.path.exists(d):
for file in os.listdir(d):
try:
os.remove(os.path.join(d, file))
except Exception:
pass
# Launch ComfyUI inside the GPU environment
print("ZeroGPU allocated. Launching ComfyUI server instance...")
comfy_process = subprocess.Popen(
[sys.executable, os.path.join(COMFYUI_DIR, "main.py"), "--listen", "127.0.0.1", "--port", "8188", "--highvram"],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True
)
# Poll local port until the server is alive
server_ready = False
for _ in range(25):
time.sleep(1)
try:
with urllib.request.urlopen("http://127.0.0.1:8188/history", timeout=1) as r:
if r.status == 200:
server_ready = True
break
except Exception:
continue
if not server_ready:
print("ComfyUI server failed to initialize within time constraints.")
comfy_process.terminate()
return None
# Enqueue the workflow
print("Server online. Enqueueing workflow...")
p = {"prompt": prompt_workflow}
data = json.dumps(p).encode('utf-8')
req = urllib.request.Request("http://127.0.0.1:8188/prompt", data=data, headers={'Content-Type': 'application/json'})
try:
with urllib.request.urlopen(req) as response:
res = json.loads(response.read().decode('utf-8'))
print(f"Workflow running. Prompt ID: {res['prompt_id']}")
except Exception as e:
print(f"API execution dispatch failed: {e}")
comfy_process.terminate()
return None
# Track output directory for the compiled image asset
generated_image_path = None
for _ in range(90):
time.sleep(1)
for d in search_dirs:
if os.path.exists(d):
files = [os.path.join(d, f) for f in os.listdir(d) if os.path.isfile(os.path.join(d, f))]
if files:
generated_image_path = max(files, key=os.path.getmtime)
break
if generated_image_path:
print(f"Asset generation complete: {generated_image_path}")
break
# Clean up the server process
comfy_process.terminate()
comfy_process.wait()
return generated_image_path
# ==========================================
# 4. Gradio Web Interface Layout
# ==========================================
with gr.Blocks() as demo:
gr.Markdown("# My Custom ComfyUI App")
gr.Markdown("Enter a prompt below to run your custom ComfyUI workflow live via ZeroGPU allocations.")
with gr.Row():
with gr.Column():
prompt_input = gr.Textbox(
label="Prompt",
value="A 3D blocky rendering of a green creature in a tan robe and chest plate, dancing in a dedicated boombox setup. Bright colors, bold lines, blocky cel shading.",
lines=5
)
submit_btn = gr.Button("Generate")
with gr.Column():
image_output = gr.Image(label="Result")
submit_btn.click(
fn=generate_image,
inputs=prompt_input,
outputs=image_output
)
if __name__ == "__main__":
demo.launch() |