File size: 4,349 Bytes
da4c8ed
 
6194646
f7e0c92
e4b37f8
0e797f9
92d864d
da4c8ed
f7e0c92
e4b37f8
f7e0c92
e4b37f8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
da4c8ed
0e797f9
e4b37f8
0e797f9
 
 
da4c8ed
e4b37f8
da4c8ed
0e797f9
 
6194646
0e797f9
f7e0c92
e4b37f8
f7e0c92
8868bd0
f9206e7
 
e4b37f8
030736b
f7e0c92
e4b37f8
 
 
f7e0c92
 
e4b37f8
f7e0c92
e4b37f8
 
 
 
5abccf3
e4b37f8
 
92d864d
f9206e7
e4b37f8
6194646
0e797f9
e4b37f8
f9206e7
6194646
e4b37f8
 
 
6194646
e4b37f8
 
0e797f9
 
5abccf3
e4b37f8
f9206e7
e4b37f8
 
 
 
92d864d
030736b
e4b37f8
 
0e797f9
f7e0c92
 
 
0e797f9
e4b37f8
 
030736b
da4c8ed
0e797f9
e4b37f8
 
f9206e7
e4b37f8
 
f9206e7
e4b37f8
f7e0c92
f9206e7
92d864d
 
242e2d2
0e797f9
457f72c
6194646
 
457f72c
f7e0c92
0e797f9
e4b37f8
92d864d
da4c8ed
 
e4b37f8
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
import gradio as gr
import torch
import random
import time
from transformers import AutoTokenizer, AutoModelForCausalLM
from diffusers import DiffusionPipeline, LCMScheduler
from PIL import Image, ImageFilter

# -------------------------------
# SMALL PROMPT ENHANCER (CPU)
# -------------------------------
ENHANCER_MODEL = "HuggingFaceTB/SmolLM-135M-Instruct"
tokenizer_enhancer = AutoTokenizer.from_pretrained(ENHANCER_MODEL)
model_enhancer = AutoModelForCausalLM.from_pretrained(ENHANCER_MODEL)

def enhance_text(user_prompt, prefix):
    """
    Uses a tiny LLM to rewrite user input into a more detailed instruction.
    """
    instruction = f"Rewrite this for an image generator with detail: {user_prompt}"
    if prefix:
        instruction = f"{prefix} {user_prompt}"

    inputs = tokenizer_enhancer(instruction, return_tensors="pt")
    outputs = model_enhancer.generate(
        **inputs,
        max_new_tokens=50,
        temperature=0.7,
        do_sample=True
    )
    text = tokenizer_enhancer.decode(outputs[0], skip_special_tokens=True)
    return text.strip()

# -------------------------------
# IMAGE MODEL SETUP (CPU SAFE)
# -------------------------------
IMG_MODEL_ID = "runwayml/stable-diffusion-v1-5"
IMG_ADAPTER_ID = "latent-consistency/lcm-lora-sdv1-5"

pipe = DiffusionPipeline.from_pretrained(
    IMG_MODEL_ID,
    torch_dtype=torch.float32,
    safety_checker=None
)
pipe.scheduler = LCMScheduler.from_config(pipe.scheduler.config)
pipe.load_lora_weights(IMG_ADAPTER_ID)
pipe.to("cpu")
pipe.enable_attention_slicing()
pipe.enable_vae_slicing()
pipe.set_progress_bar_config(disable=True)

# -------------------------------
# ETA
# -------------------------------
def estimate_time(steps, resolution):
    steps = int(steps)
    resolution = int(resolution)
    per_step = {512:12, 768:25, 1024:45}[resolution]
    overhead = 2
    est = overhead + steps * per_step
    mins = est // 60
    secs = est % 60
    return f"⏱️ Estimated: ~{mins}m {secs}s"

# -------------------------------
# GENERATE WITH PROGRESSIVE BLUR
# -------------------------------
def generate(prompt, neg_prompt, resolution, steps):
    # 1️⃣ AI PROMPT ENHANCEMENT
    enhanced_prompt = enhance_text(prompt, "")
    enhanced_negative = enhance_text(neg_prompt, "Rewrite negative prompt:")

    # 2️⃣ White placeholder
    placeholder = Image.new("RGB", (int(resolution), int(resolution)), (255,255,255))
    yield [placeholder], "🟡 Generating..."

    # 3️⃣ CPU IMAGE GENERATION
    seed = random.randint(0, 10**9)
    gen = torch.Generator("cpu").manual_seed(seed)
    pipe.scheduler.set_timesteps(int(steps))

    img = pipe(
        prompt=enhanced_prompt,
        negative_prompt=enhanced_negative,
        num_inference_steps=int(steps),
        guidance_scale=1.2,
        width=int(resolution),
        height=int(resolution),
        generator=gen
    ).images[0]

    # 4️⃣ BLUR REVEAL
    max_blur = 20
    for i in range(10):
        blur_pct = 100 - i*10
        blurred = img.filter(ImageFilter.GaussianBlur(radius=max_blur * blur_pct/100))
        yield [blurred], "🟢 Revealing..."
        time.sleep(1)

    # 5️⃣ FINAL
    yield [img], f"✅ Done | Seed: {seed}"

# -------------------------------
# GRADIO UI
# -------------------------------
with gr.Blocks(theme=gr.themes.Soft()) as demo:
    gr.Markdown("# 👾 CREEPER AI — SMART IMAGE GENERATOR")
    gr.Markdown("1: The higher the resolution & steps, the longer the image takes to make.\n2: The more detailed the prompt and negative prompt, the better the result.")

    with gr.Row():
        with gr.Column():
            prompt_in = gr.Textbox(label="Prompt")
            neg_in = gr.Textbox(label="Negative Prompt")

            resolution = gr.Radio([512, 768, 1024], value=512, label="Resolution")
            steps = gr.Slider(6,8,value=6,step=1,label="Steps")

            eta = gr.Markdown("⏱️ Estimated: ~1m 0s")
            gen_btn = gr.Button("Generate")

            status = gr.Markdown("🟢 Ready")

        with gr.Column():
            gallery = gr.Gallery(columns=1)

    for ctrl in [steps, resolution]:
        ctrl.change(estimate_time, [steps, resolution], eta)

    gen_btn.click(
        generate,
        inputs=[prompt_in, neg_in, resolution, steps],
        outputs=[gallery, status]
    )

demo.launch()