Spaces:
Starting
Starting
Update app.py
Browse files
app.py
CHANGED
@@ -6,7 +6,6 @@ import spaces
|
|
6 |
from diffusers import DiffusionPipeline, AutoencoderTiny, AutoencoderKL
|
7 |
from live_preview_helpers import calculate_shift, retrieve_timesteps, flux_pipe_call_that_returns_an_iterable_of_images
|
8 |
from diffusers.utils import load_image
|
9 |
-
import pandas as pd
|
10 |
import random
|
11 |
import time
|
12 |
|
@@ -17,10 +16,6 @@ KRYPTO_LORA = {
|
|
17 |
"adapter_name": "krypt0"
|
18 |
}
|
19 |
|
20 |
-
# Load prompts for the randomize button
|
21 |
-
df = pd.read_csv('prompts.csv', header=None)
|
22 |
-
prompt_values = df.values.flatten()
|
23 |
-
|
24 |
# Get access token from Space secrets
|
25 |
HF_TOKEN = os.getenv("HF_TOKEN")
|
26 |
if not HF_TOKEN:
|
@@ -44,7 +39,8 @@ print(f"Loading on-board LoRA: {KRYPTO_LORA['repo']}")
|
|
44 |
pipe.load_lora_weights(
|
45 |
KRYPTO_LORA['repo'],
|
46 |
low_cpu_mem_usage=True,
|
47 |
-
adapter_name=KRYPTO_LORA['adapter_name']
|
|
|
48 |
)
|
49 |
print("LoRA loaded successfully.")
|
50 |
|
@@ -55,7 +51,6 @@ pipe.flux_pipe_call_that_returns_an_iterable_of_images = flux_pipe_call_that_ret
|
|
55 |
|
56 |
|
57 |
def calculate_dimensions(aspect_ratio, resolution):
|
58 |
-
"""Calculates width and height based on aspect ratio and base resolution."""
|
59 |
resolution = int(resolution)
|
60 |
if aspect_ratio == "Square (1:1)":
|
61 |
width, height = resolution, resolution
|
@@ -65,16 +60,13 @@ def calculate_dimensions(aspect_ratio, resolution):
|
|
65 |
width, height = resolution, int(resolution * 9 / 16)
|
66 |
elif aspect_ratio == "Ultrawide (21:9)":
|
67 |
width, height = resolution, int(resolution * 9 / 21)
|
68 |
-
else:
|
69 |
width, height = resolution, resolution
|
70 |
-
# Ensure dimensions are multiples of 64 for optimal performance
|
71 |
width = (width // 64) * 64
|
72 |
height = (height // 64) * 64
|
73 |
return width, height
|
74 |
|
75 |
def generate_image(prompt_mash, steps, seed, cfg_scale, width, height, progress):
|
76 |
-
"""Generator function for text-to-image with live preview."""
|
77 |
-
# The parent @spaces.GPU function has already allocated a GPU
|
78 |
pipe.to(device)
|
79 |
generator = torch.Generator(device=device).manual_seed(seed)
|
80 |
|
@@ -89,7 +81,6 @@ def generate_image(prompt_mash, steps, seed, cfg_scale, width, height, progress)
|
|
89 |
output_type="pil",
|
90 |
good_vae=good_vae,
|
91 |
)
|
92 |
-
# Yield previews and the final image
|
93 |
final_image = None
|
94 |
for i, image in enumerate(image_generator):
|
95 |
final_image = image
|
@@ -98,8 +89,7 @@ def generate_image(prompt_mash, steps, seed, cfg_scale, width, height, progress)
|
|
98 |
yield final_image, gr.update(visible=False)
|
99 |
|
100 |
def update_history(new_image, history):
|
101 |
-
|
102 |
-
if new_image is None: # Don't add empty images on error
|
103 |
return history
|
104 |
if history is None:
|
105 |
history = []
|
@@ -111,10 +101,17 @@ def run_generation(prompt, lora_scale, cfg_scale, steps, randomize_seed, seed, a
|
|
111 |
if not prompt:
|
112 |
raise gr.Error("Prompt cannot be empty.")
|
113 |
|
114 |
-
|
115 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
|
117 |
-
# Activate the LoRA adapter with the slider's weight
|
118 |
pipe.set_adapters([KRYPTO_LORA['adapter_name']], adapter_weights=[lora_scale])
|
119 |
print(f"Adapter '{KRYPTO_LORA['adapter_name']}' activated with weight {lora_scale}.")
|
120 |
|
@@ -124,7 +121,6 @@ def run_generation(prompt, lora_scale, cfg_scale, steps, randomize_seed, seed, a
|
|
124 |
width, height = calculate_dimensions(aspect_ratio, base_resolution)
|
125 |
print(f"Generating a {width}x{height} image.")
|
126 |
|
127 |
-
# The function now only handles text-to-image
|
128 |
for image, progress_update in generate_image(prompt_mash, steps, seed, cfg_scale, width, height, progress):
|
129 |
yield image, seed, progress_update
|
130 |
|
@@ -132,41 +128,58 @@ run_generation.zerogpu = True
|
|
132 |
|
133 |
# --- User Interface (Gradio) ---
|
134 |
css = '''
|
135 |
-
#
|
136 |
-
#
|
137 |
-
#
|
|
|
138 |
.progress-container {width: 100%;height: 30px;background-color: #f0f0f0;border-radius: 15px;overflow: hidden;margin-bottom: 20px}
|
139 |
.progress-bar {height: 100%;background-color: #4f46e5;width: calc(var(--current) / var(--total) * 100%);transition: width 0.1s ease-in-out}
|
140 |
-
#random_prompt_btn{max-width: 2.5em; min-width: 2.5em !important; height: 100% !important;}
|
141 |
'''
|
142 |
|
143 |
with gr.Blocks(css=css, theme=gr.themes.Soft()) as app:
|
144 |
# --- Header ---
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
|
150 |
with gr.Row():
|
151 |
# --- LEFT COLUMN: CONTROLS ---
|
152 |
with gr.Column(scale=3):
|
153 |
-
# Prompt
|
154 |
with gr.Group():
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
# Image Shape Controls
|
162 |
-
aspect_ratio = gr.Radio(
|
163 |
-
label="Aspect Ratio",
|
164 |
-
choices=["Square (1:1)", "Portrait (9:16)", "Landscape (16:9)", "Ultrawide (21:9)"],
|
165 |
-
value="Square (1:1)"
|
166 |
-
)
|
167 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
# Advanced Settings
|
169 |
-
with gr.Accordion("Advanced Settings", open=
|
170 |
base_resolution = gr.Slider(label="Resolution (longest side)", minimum=768, maximum=1408, step=64, value=1024)
|
171 |
steps = gr.Slider(label="Generation Steps", minimum=4, maximum=50, step=1, value=20)
|
172 |
cfg_scale = gr.Slider(label="Guidance (CFG Scale)", minimum=1, maximum=10, step=0.5, value=3.5)
|
@@ -185,15 +198,6 @@ with gr.Blocks(css=css, theme=gr.themes.Soft()) as app:
|
|
185 |
history_gallery = gr.Gallery(label="History", columns=4, object_fit="contain", interactive=False)
|
186 |
|
187 |
# --- Event Logic ---
|
188 |
-
def get_random_prompt():
|
189 |
-
return random.choice(prompt_values)
|
190 |
-
|
191 |
-
random_prompt_btn.click(
|
192 |
-
fn=get_random_prompt,
|
193 |
-
inputs=[],
|
194 |
-
outputs=[prompt]
|
195 |
-
)
|
196 |
-
|
197 |
generation_event = gr.on(
|
198 |
triggers=[generate_button.click, prompt.submit],
|
199 |
fn=run_generation,
|
|
|
6 |
from diffusers import DiffusionPipeline, AutoencoderTiny, AutoencoderKL
|
7 |
from live_preview_helpers import calculate_shift, retrieve_timesteps, flux_pipe_call_that_returns_an_iterable_of_images
|
8 |
from diffusers.utils import load_image
|
|
|
9 |
import random
|
10 |
import time
|
11 |
|
|
|
16 |
"adapter_name": "krypt0"
|
17 |
}
|
18 |
|
|
|
|
|
|
|
|
|
19 |
# Get access token from Space secrets
|
20 |
HF_TOKEN = os.getenv("HF_TOKEN")
|
21 |
if not HF_TOKEN:
|
|
|
39 |
pipe.load_lora_weights(
|
40 |
KRYPTO_LORA['repo'],
|
41 |
low_cpu_mem_usage=True,
|
42 |
+
adapter_name=KRYPTO_LORA['adapter_name'],
|
43 |
+
token=HF_TOKEN
|
44 |
)
|
45 |
print("LoRA loaded successfully.")
|
46 |
|
|
|
51 |
|
52 |
|
53 |
def calculate_dimensions(aspect_ratio, resolution):
|
|
|
54 |
resolution = int(resolution)
|
55 |
if aspect_ratio == "Square (1:1)":
|
56 |
width, height = resolution, resolution
|
|
|
60 |
width, height = resolution, int(resolution * 9 / 16)
|
61 |
elif aspect_ratio == "Ultrawide (21:9)":
|
62 |
width, height = resolution, int(resolution * 9 / 21)
|
63 |
+
else:
|
64 |
width, height = resolution, resolution
|
|
|
65 |
width = (width // 64) * 64
|
66 |
height = (height // 64) * 64
|
67 |
return width, height
|
68 |
|
69 |
def generate_image(prompt_mash, steps, seed, cfg_scale, width, height, progress):
|
|
|
|
|
70 |
pipe.to(device)
|
71 |
generator = torch.Generator(device=device).manual_seed(seed)
|
72 |
|
|
|
81 |
output_type="pil",
|
82 |
good_vae=good_vae,
|
83 |
)
|
|
|
84 |
final_image = None
|
85 |
for i, image in enumerate(image_generator):
|
86 |
final_image = image
|
|
|
89 |
yield final_image, gr.update(visible=False)
|
90 |
|
91 |
def update_history(new_image, history):
|
92 |
+
if new_image is None:
|
|
|
93 |
return history
|
94 |
if history is None:
|
95 |
history = []
|
|
|
101 |
if not prompt:
|
102 |
raise gr.Error("Prompt cannot be empty.")
|
103 |
|
104 |
+
# --- NOUVELLE LOGIQUE DE PROMPT ---
|
105 |
+
# Définition des parties fixes du prompt
|
106 |
+
prefix_prompt = f"{KRYPTO_LORA['trigger']}, Krypt0 the white scruffy superdog with a red cape,"
|
107 |
+
suffix_prompt = ", This is a cinematic, ultra-high-detail, photorealistic still"
|
108 |
+
|
109 |
+
# Construction du prompt final
|
110 |
+
user_prompt = prompt # Le prompt entré par l'utilisateur
|
111 |
+
prompt_mash = f"{prefix_prompt} {user_prompt}{suffix_prompt}"
|
112 |
+
|
113 |
+
print("Final prompt sent to model:", prompt_mash)
|
114 |
|
|
|
115 |
pipe.set_adapters([KRYPTO_LORA['adapter_name']], adapter_weights=[lora_scale])
|
116 |
print(f"Adapter '{KRYPTO_LORA['adapter_name']}' activated with weight {lora_scale}.")
|
117 |
|
|
|
121 |
width, height = calculate_dimensions(aspect_ratio, base_resolution)
|
122 |
print(f"Generating a {width}x{height} image.")
|
123 |
|
|
|
124 |
for image, progress_update in generate_image(prompt_mash, steps, seed, cfg_scale, width, height, progress):
|
125 |
yield image, seed, progress_update
|
126 |
|
|
|
128 |
|
129 |
# --- User Interface (Gradio) ---
|
130 |
css = '''
|
131 |
+
#title_container { text-align: center; margin-bottom: 1em; }
|
132 |
+
#title_line { display: flex; justify-content: center; align-items: center; }
|
133 |
+
#title_line h1 { font-size: 2.5em; margin: 0; }
|
134 |
+
#subtitle { font-size: 1.1em; color: #57606a; margin-top: 0.3em; }
|
135 |
.progress-container {width: 100%;height: 30px;background-color: #f0f0f0;border-radius: 15px;overflow: hidden;margin-bottom: 20px}
|
136 |
.progress-bar {height: 100%;background-color: #4f46e5;width: calc(var(--current) / var(--total) * 100%);transition: width 0.1s ease-in-out}
|
|
|
137 |
'''
|
138 |
|
139 |
with gr.Blocks(css=css, theme=gr.themes.Soft()) as app:
|
140 |
# --- Header ---
|
141 |
+
gr.HTML(
|
142 |
+
"""
|
143 |
+
<div id="title_container">
|
144 |
+
<div id="title_line">
|
145 |
+
<h1>Krypto Image Generator - beta v1</h1>
|
146 |
+
</div>
|
147 |
+
<div id="subtitle">
|
148 |
+
Powered by $Krypto | @Kryptocoinonsol
|
149 |
+
</div>
|
150 |
+
</div>
|
151 |
+
"""
|
152 |
+
)
|
153 |
|
154 |
with gr.Row():
|
155 |
# --- LEFT COLUMN: CONTROLS ---
|
156 |
with gr.Column(scale=3):
|
157 |
+
# Prompt Controls (Simplifié)
|
158 |
with gr.Group():
|
159 |
+
prompt = gr.Textbox(
|
160 |
+
label="Prompt",
|
161 |
+
lines=3,
|
162 |
+
placeholder="Krypto the superdog sits in the snow, with snow on his muzzle, looking innocent. It's a medium shot of the dog, and the image creates a friendly atmosphere."
|
163 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
164 |
|
165 |
+
# Image Shape and Style Controls
|
166 |
+
with gr.Group():
|
167 |
+
aspect_ratio = gr.Radio(
|
168 |
+
label="Aspect Ratio",
|
169 |
+
choices=["Square (1:1)", "Portrait (9:16)", "Landscape (16:9)", "Ultrawide (21:9)"],
|
170 |
+
value="Square (1:1)"
|
171 |
+
)
|
172 |
+
lora_scale = gr.Slider(
|
173 |
+
label="Krypt0 Style Strength",
|
174 |
+
minimum=0,
|
175 |
+
maximum=2,
|
176 |
+
step=0.05,
|
177 |
+
value=0.9,
|
178 |
+
info="Controls how strongly the artistic style is applied. Higher values mean a more stylized image."
|
179 |
+
)
|
180 |
+
|
181 |
# Advanced Settings
|
182 |
+
with gr.Accordion("Advanced Settings", open=False):
|
183 |
base_resolution = gr.Slider(label="Resolution (longest side)", minimum=768, maximum=1408, step=64, value=1024)
|
184 |
steps = gr.Slider(label="Generation Steps", minimum=4, maximum=50, step=1, value=20)
|
185 |
cfg_scale = gr.Slider(label="Guidance (CFG Scale)", minimum=1, maximum=10, step=0.5, value=3.5)
|
|
|
198 |
history_gallery = gr.Gallery(label="History", columns=4, object_fit="contain", interactive=False)
|
199 |
|
200 |
# --- Event Logic ---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
201 |
generation_event = gr.on(
|
202 |
triggers=[generate_button.click, prompt.submit],
|
203 |
fn=run_generation,
|