Change Torch references
Browse files- README.md +1 -1
- app.py +774 -407
- pre-requirements.txt +5 -1
- requirements.txt +20 -12
- src/condition.py +11 -9
- utils/ai_generator.py +8 -6
- utils/ai_generator_diffusers_flux.py +57 -37
- utils/constants.py +32 -12
- utils/misc.py +78 -0
- utils/version_info.py +40 -7
README.md
CHANGED
@@ -5,7 +5,7 @@ colorFrom: yellow
|
|
5 |
colorTo: purple
|
6 |
sdk: gradio
|
7 |
python_version: 3.10.13
|
8 |
-
sdk_version: 5.
|
9 |
app_file: app.py
|
10 |
pinned: false
|
11 |
short_description: Transform Your Images into Mesmerizing Hexagon Grids
|
|
|
5 |
colorTo: purple
|
6 |
sdk: gradio
|
7 |
python_version: 3.10.13
|
8 |
+
sdk_version: 5.16.0
|
9 |
app_file: app.py
|
10 |
pinned: false
|
11 |
short_description: Transform Your Images into Mesmerizing Hexagon Grids
|
app.py
CHANGED
@@ -1,14 +1,15 @@
|
|
1 |
-
import
|
|
|
|
|
2 |
import gradio as gr
|
3 |
from PIL import Image
|
4 |
from haishoku.haishoku import Haishoku
|
5 |
-
|
6 |
from tempfile import NamedTemporaryFile
|
7 |
#from pathlib import Path
|
8 |
import atexit
|
9 |
import random
|
10 |
-
|
11 |
-
import utils.constants as constants
|
12 |
|
13 |
IS_SHARED_SPACE = constants.IS_SHARED_SPACE
|
14 |
|
@@ -20,7 +21,7 @@ from utils.color_utils import (
|
|
20 |
detect_color_format,
|
21 |
update_color_opacity,
|
22 |
)
|
23 |
-
from utils.misc import (get_filename, pause, convert_ratio_to_dimensions)
|
24 |
from utils.depth_estimation import estimate_depth, create_3d_model, generate_depth_and_3d, generate_depth_button_click
|
25 |
|
26 |
from utils.image_utils import (
|
@@ -33,7 +34,8 @@ from utils.image_utils import (
|
|
33 |
show_lut,
|
34 |
apply_lut_to_image_path,
|
35 |
multiply_and_blend_images,
|
36 |
-
alpha_composite_with_control
|
|
|
37 |
)
|
38 |
|
39 |
from utils.hex_grid import (
|
@@ -50,11 +52,13 @@ from utils.excluded_colors import (
|
|
50 |
on_color_display_select
|
51 |
)
|
52 |
|
53 |
-
from utils.ai_generator import (
|
54 |
-
|
55 |
-
)
|
56 |
from utils.version_info import (
|
57 |
versions_html,
|
|
|
|
|
58 |
get_torch_info
|
59 |
)
|
60 |
from utils.lora_details import (
|
@@ -138,8 +142,7 @@ def hex_create(hex_size, border_size, input_image_path, start_x, start_y, end_x,
|
|
138 |
add_hex_text_option,
|
139 |
custom_text_list,
|
140 |
custom_text_color_list
|
141 |
-
)
|
142 |
-
|
143 |
return grid_image
|
144 |
|
145 |
def get_model_and_lora(model_textbox):
|
@@ -159,7 +162,324 @@ def get_model_and_lora(model_textbox):
|
|
159 |
default_model = model_textbox
|
160 |
return default_model, []
|
161 |
|
162 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
# Get the model and LoRA weights
|
164 |
model, lora_weights = get_model_and_lora(model_textbox_value)
|
165 |
global current_prerendered_image
|
@@ -168,7 +488,7 @@ def generate_input_image_click(map_option, prompt_textbox_value, negative_prompt
|
|
168 |
if use_conditioned_image:
|
169 |
print(f"Conditioned path: {current_prerendered_image.value}.. converting to RGB\n")
|
170 |
# ensure the conditioned image is an image and not a string, cannot use RGBA
|
171 |
-
if isinstance(current_prerendered_image.value, str):
|
172 |
conditioned_image = open_image(current_prerendered_image.value).convert("RGB")
|
173 |
print(f"Conditioned Image: {conditioned_image.size}.. converted to RGB\n")
|
174 |
|
@@ -176,20 +496,23 @@ def generate_input_image_click(map_option, prompt_textbox_value, negative_prompt
|
|
176 |
width_ratio, height_ratio = map(int, image_format.split(":"))
|
177 |
aspect_ratio = width_ratio / height_ratio
|
178 |
|
179 |
-
width, height = convert_ratio_to_dimensions(aspect_ratio,
|
180 |
-
|
|
|
|
|
181 |
# Generate the AI image and get the image path
|
182 |
-
image_path =
|
183 |
map_option,
|
184 |
prompt_textbox_value,
|
185 |
negative_prompt_textbox_value,
|
186 |
model,
|
187 |
lora_weights,
|
188 |
conditioned_image,
|
189 |
-
|
190 |
height=height,
|
191 |
width=width,
|
192 |
-
seed=seed
|
|
|
193 |
)
|
194 |
|
195 |
# Open the generated image
|
@@ -207,7 +530,7 @@ def generate_input_image_click(map_option, prompt_textbox_value, negative_prompt
|
|
207 |
upscaled_image.save(tmp_upscaled.name, format="PNG")
|
208 |
constants.temp_files.append(tmp_upscaled.name)
|
209 |
print(f"Upscaled image saved to {tmp_upscaled.name}")
|
210 |
-
|
211 |
# Return the path of the upscaled image
|
212 |
return tmp_upscaled.name
|
213 |
|
@@ -236,423 +559,467 @@ def combine_images_with_lerp(input_image, output_image, alpha):
|
|
236 |
print(f"Combining images with alpha: {alpha}")
|
237 |
return lerp_imagemath(in_image, out_image, alpha)
|
238 |
|
239 |
-
def add_border(image, mask_width, mask_height, blank_color):
|
|
|
240 |
bordered_image_output = Image.open(image).convert("RGBA")
|
241 |
margin_color = detect_color_format(blank_color)
|
242 |
print(f"Adding border to image with width: {mask_width}, height: {mask_height}, color: {margin_color}")
|
243 |
return shrink_and_paste_on_blank(bordered_image_output, mask_width, mask_height, margin_color)
|
|
|
|
|
|
|
|
|
244 |
|
245 |
-
|
246 |
-
description = "Customizable Hexagon Grid Image Generator"
|
247 |
-
examples = [["assets//examples//hex_map_p1.png", 32, 1, 0, 0, 0, 0, 0, "#ede9ac44","#12165380", True]]
|
248 |
|
249 |
-
|
250 |
-
|
251 |
-
with gr.
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
gr.Markdown ("""
|
259 |
|
260 |
-
|
261 |
|
262 |
|
263 |
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
### What Can You Do?
|
268 |
-
- **Generate Hexagon Grids:** Create beautiful hexagon grid overlays on any image with fully customizable parameters.
|
269 |
-
- **AI-Powered Image Generation:** Use advanced AI models to generate images based on your prompts and apply hexagon grids to them.
|
270 |
-
- **Color Exclusion:** Select and exclude specific colors from your hexagon grid for a cleaner and more refined look.
|
271 |
-
- **Interactive Customization:** Adjust hexagon size, border size, rotation, background color, and more in real-time.
|
272 |
-
- **Depth and 3D Model Generation:** Generate depth maps and 3D models from your images for enhanced visualization.
|
273 |
-
- **Image Filter [Look-Up Table (LUT)] Application:** Apply filters (LUTs) to your images for color grading and enhancement.
|
274 |
-
- **Pre-rendered Maps:** Access a library of pre-rendered hexagon maps for quick and easy customization.
|
275 |
-
- **Add Margins:** Add customizable margins around your images for a polished finish.
|
276 |
-
|
277 |
-
### Why You'll Love It
|
278 |
-
- **Fun and Easy to Use:** With an intuitive interface and real-time previews, creating hexagon grids has never been this fun!
|
279 |
-
- **Endless Creativity:** Unleash your creativity with endless customization options and see your images transform in unique ways.
|
280 |
-
- **Hexagon-Inspired Theme:** Enjoy a delightful yellow and purple theme inspired by hexagons! ⬢
|
281 |
-
- **Advanced AI Models:** Leverage advanced AI models and LoRA weights for high-quality image generation and customization.
|
282 |
-
|
283 |
-
### Get Started
|
284 |
-
1. **Upload or Generate an Image:** Start by uploading your own image or generate one using our AI-powered tool.
|
285 |
-
2. **Customize Your Grid:** Play around with the settings to create the perfect hexagon grid overlay.
|
286 |
-
3. **Download and Share:** Once you're happy with your creation, download it and share it with the world!
|
287 |
-
|
288 |
-
### Advanced Features
|
289 |
-
- **Generative AI Integration:** Utilize models like `black-forest-labs/FLUX.1-dev` and various LoRA weights for generating unique images.
|
290 |
-
- **Pre-rendered Maps:** Access a library of pre-rendered hexagon maps for quick and easy customization.
|
291 |
-
- **Image Filter [Look-Up Table (LUT)] Application:** Apply filters (LUTs) to your images for color grading and enhancement.
|
292 |
-
- **Depth and 3D Model Generation:** Create depth maps and 3D models from your images for enhanced visualization.
|
293 |
-
- **Add Margins:** Customize margins around your images for a polished finish.
|
294 |
-
|
295 |
-
Join the hive and start creating with HexaGrid Creator today!
|
296 |
-
|
297 |
-
""", elem_classes="intro")
|
298 |
-
with gr.Row():
|
299 |
-
from utils.image_utils import convert_to_rgba_png
|
300 |
-
|
301 |
-
# Existing code
|
302 |
-
with gr.Column(scale=2):
|
303 |
-
input_image = gr.Image(
|
304 |
-
label="Input Image",
|
305 |
-
type="filepath",
|
306 |
-
interactive=True,
|
307 |
-
elem_classes="centered solid imgcontainer",
|
308 |
-
key="imgInput",
|
309 |
-
image_mode=None,
|
310 |
-
format="PNG",
|
311 |
-
show_download_button=True,
|
312 |
-
)
|
313 |
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
fn=on_input_image_change,
|
324 |
-
inputs=[input_image],
|
325 |
-
outputs=[input_image], scroll_to_output=True,
|
326 |
-
)
|
327 |
-
with gr.Column():
|
328 |
-
with gr.Accordion("Hex Coloring and Exclusion", open = False):
|
329 |
-
with gr.Row():
|
330 |
-
with gr.Column():
|
331 |
-
color_picker = gr.ColorPicker(label="Pick a color to exclude",value="#505050")
|
332 |
-
with gr.Column():
|
333 |
-
filter_color = gr.Checkbox(label="Filter Excluded Colors from Sampling", value=False,)
|
334 |
-
exclude_color_button = gr.Button("Exclude Color", elem_id="exlude_color_button", elem_classes="solid")
|
335 |
-
color_display = gr.DataFrame(label="List of Excluded RGBA Colors", headers=["R", "G", "B", "A"], elem_id="excluded_colors", type="array", value=build_dataframe(excluded_color_list), interactive=True, elem_classes="solid centered")
|
336 |
-
selected_row = gr.Number(0, label="Selected Row", visible=False)
|
337 |
-
delete_button = gr.Button("Delete Row", elem_id="delete_exclusion_button", elem_classes="solid")
|
338 |
-
fill_hex = gr.Checkbox(label="Fill Hex with color from Image", value=True)
|
339 |
-
with gr.Accordion("Image Filters", open = False):
|
340 |
-
with gr.Row():
|
341 |
-
with gr.Column():
|
342 |
-
composite_color = gr.ColorPicker(label="Color", value="#ede9ac44")
|
343 |
-
with gr.Column():
|
344 |
-
composite_opacity = gr.Slider(label="Opacity %", minimum=0, maximum=100, value=50, interactive=True)
|
345 |
-
with gr.Row():
|
346 |
-
composite_button = gr.Button("Composite", elem_classes="solid")
|
347 |
-
with gr.Row():
|
348 |
-
with gr.Column():
|
349 |
-
lut_filename = gr.Textbox(
|
350 |
-
value="",
|
351 |
-
label="Look Up Table (LUT) File Name",
|
352 |
-
elem_id="lutFileName")
|
353 |
-
with gr.Column():
|
354 |
-
lut_file = gr.File(
|
355 |
-
value=None,
|
356 |
-
file_count="single",
|
357 |
-
file_types=[".cube"],
|
358 |
-
type="filepath",
|
359 |
-
label="LUT cube File")
|
360 |
-
with gr.Row():
|
361 |
-
lut_example_image = gr.Image(type="pil", label="Filter (LUT) Example Image", value=constants.default_lut_example_img)
|
362 |
-
with gr.Row():
|
363 |
-
with gr.Column():
|
364 |
-
gr.Markdown("""
|
365 |
-
### Included Filters (LUTs)
|
366 |
-
There are several included Filters:
|
367 |
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
388 |
)
|
389 |
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
visible=False
|
406 |
-
)
|
407 |
-
# Update map_options to a Dropdown with choices from constants.PROMPTS keys
|
408 |
with gr.Row():
|
409 |
with gr.Column():
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
417 |
with gr.Column():
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
|
|
|
|
422 |
with gr.Column():
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
value=0,
|
429 |
-
scale=0
|
430 |
)
|
431 |
-
|
432 |
-
prompt_textbox = gr.Textbox(
|
433 |
-
label="Prompt",
|
434 |
-
visible=False,
|
435 |
-
elem_classes="solid",
|
436 |
-
value="top-down, (tabletop_map built from small hexagon pieces) hexagon map of a Battletech_boardgame forest with lakes, forest, magic fauna, and snow at the top and bottom, (middle is dark, no_reflections, no_shadows) , tall and short hexagon tiles. Viewed from above.",
|
437 |
-
lines=4
|
438 |
-
)
|
439 |
-
negative_prompt_textbox = gr.Textbox(
|
440 |
-
label="Negative Prompt",
|
441 |
-
visible=False,
|
442 |
-
elem_classes="solid",
|
443 |
-
value="low quality, bad anatomy, blurry, cropped, worst quality, shadows, people, humans, reflections, shadows, realistic map of the Earth, isometric, text"
|
444 |
-
)
|
445 |
-
prompt_notes_label = gr.Label(
|
446 |
-
"You should use FRM$ as trigger words. @1.5 minutes",
|
447 |
-
elem_classes="solid centered small",
|
448 |
-
show_label=False,
|
449 |
-
visible=False
|
450 |
-
)
|
451 |
-
# Keep the change event to maintain functionality
|
452 |
-
map_options.change(
|
453 |
-
fn=update_prompt_visibility,
|
454 |
-
inputs=[map_options],
|
455 |
-
outputs=[prompt_textbox, negative_prompt_textbox, prompt_notes_label]
|
456 |
-
)
|
457 |
with gr.Row():
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
|
|
|
|
|
|
|
|
|
|
462 |
)
|
463 |
-
|
464 |
-
with gr.Accordion("Template Image Styles", open = False):
|
465 |
-
with gr.Row():
|
466 |
-
# Gallery from PRE_RENDERED_IMAGES GOES HERE
|
467 |
-
prerendered_image_gallery = gr.Gallery(label="Image Gallery", show_label=True, value=build_prerendered_images(constants.pre_rendered_maps_paths), elem_id="gallery", elem_classes="solid", type="filepath", columns=[3], rows=[3], preview=False ,object_fit="contain", height="auto",file_types=["image"], format="png",allow_preview=False)
|
468 |
-
with gr.Row():
|
469 |
-
image_guidance_stength = gr.Slider(label="Image Guidance Strength", minimum=0, maximum=1.0, value=0.5, step=0.05, interactive=True)
|
470 |
-
with gr.Column():
|
471 |
-
replace_input_image_button = gr.Button(
|
472 |
-
"Replace Input Image",
|
473 |
-
elem_id="prerendered_replace_input_image_button",
|
474 |
-
elem_classes="solid"
|
475 |
-
)
|
476 |
-
with gr.Column():
|
477 |
-
generate_input_image_from_gallery = gr.Button(
|
478 |
-
"Generate AI Image from Gallery",
|
479 |
-
elem_id="generate_input_image_from_gallery",
|
480 |
-
elem_classes="solid"
|
481 |
-
)
|
482 |
-
|
483 |
-
with gr.Accordion("Advanced Hexagon Settings", open = False):
|
484 |
-
with gr.Row():
|
485 |
-
start_x = gr.Number(label="Start X", value=0, minimum=-512, maximum= 512, precision=0)
|
486 |
-
start_y = gr.Number(label="Start Y", value=0, minimum=-512, maximum= 512, precision=0)
|
487 |
-
end_x = gr.Number(label="End X", value=0, minimum=-512, maximum= 512, precision=0)
|
488 |
-
end_y = gr.Number(label="End Y", value=0, minimum=-512, maximum= 512, precision=0)
|
489 |
-
with gr.Row():
|
490 |
-
x_spacing = gr.Number(label="Adjust Horizontal spacing", value=-1, minimum=-200, maximum=200, precision=1)
|
491 |
-
y_spacing = gr.Number(label="Adjust Vertical spacing", value=1, minimum=-200, maximum=200, precision=1)
|
492 |
-
with gr.Row():
|
493 |
-
rotation = gr.Slider(-90, 180, 0.0, 0.1, label="Hexagon Rotation (degree)")
|
494 |
-
add_hex_text = gr.Dropdown(label="Add Text to Hexagons", choices=[None, "Row-Column Coordinates", "Sequential Numbers", "Playing Cards Sequential", "Playing Cards Alternate Red and Black", "Custom List"], value=None)
|
495 |
-
with gr.Row():
|
496 |
-
custom_text_list = gr.TextArea(label="Custom Text List", value=constants.cards_alternating, visible=False,)
|
497 |
-
custom_text_color_list = gr.TextArea(label="Custom Text Color List", value=constants.card_colors_alternating, visible=False)
|
498 |
-
with gr.Row():
|
499 |
-
hex_text_info = gr.Markdown("""
|
500 |
-
### Text Color uses the Border Color and Border Opacity, unless you use a custom list.
|
501 |
-
### The Custom Text List and Custom Text Color List are comma separated lists.
|
502 |
-
### The custom color list is a comma separated list of hex colors.
|
503 |
-
#### Example: "A,2,3,4,5,6,7,8,9,10,J,Q,K", "red,#0000FF,#00FF00,red,#FFFF00,#00FFFF,#FF8000,#FF00FF,#FF0080,#FF8000,#FF0080,lightblue"
|
504 |
-
""", elem_id="hex_text_info", visible=False)
|
505 |
-
add_hex_text.change(
|
506 |
-
fn=lambda x: (
|
507 |
-
gr.update(visible=(x == "Custom List")),
|
508 |
-
gr.update(visible=(x == "Custom List")),
|
509 |
-
gr.update(visible=(x != None))
|
510 |
-
),
|
511 |
-
inputs=add_hex_text,
|
512 |
-
outputs=[custom_text_list, custom_text_color_list, hex_text_info]
|
513 |
-
)
|
514 |
-
with gr.Row():
|
515 |
-
hex_size = gr.Number(label="Hexagon Size", value=32, minimum=1, maximum=768)
|
516 |
-
border_size = gr.Slider(-5,25,value=0,step=1,label="Border Size")
|
517 |
-
with gr.Row():
|
518 |
-
background_color = gr.ColorPicker(label="Background Color", value="#000000", interactive=True)
|
519 |
-
background_opacity = gr.Slider(0,100,0,1,label="Background Opacity %")
|
520 |
-
border_color = gr.ColorPicker(label="Border Color", value="#7b7b7b", interactive=True)
|
521 |
-
border_opacity = gr.Slider(0,100,0,1,label="Border Opacity %")
|
522 |
-
with gr.Row():
|
523 |
-
hex_button = gr.Button("Generate Hex Grid!", elem_classes="solid", elem_id="btn-generate")
|
524 |
-
with gr.Row():
|
525 |
-
output_image = gr.Image(label="Hexagon Grid Image", image_mode = "RGBA", show_download_button=True, show_share_button=True,elem_classes="centered solid imgcontainer", format="PNG", type="filepath", key="ImgOutput")
|
526 |
-
overlay_image = gr.Image(label="Hexagon Overlay Image", image_mode = "RGBA", show_share_button=True, elem_classes="centered solid imgcontainer", format="PNG", type="filepath", key="ImgOverlay")
|
527 |
-
with gr.Row():
|
528 |
-
output_overlay_composite = gr.Slider(0,100,50,0.5, label="Interpolate Intensity")
|
529 |
-
output_blend_multiply_composite = gr.Slider(0,100,50,0.5, label="Overlay Intensity")
|
530 |
-
output_alpha_composite = gr.Slider(0,100,50,0.5, label="Alpha Composite Intensity")
|
531 |
-
with gr.Accordion("Add Margins (bleed)", open=False):
|
532 |
with gr.Row():
|
533 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
534 |
with gr.Row():
|
535 |
-
|
536 |
-
|
|
|
|
|
|
|
|
|
|
|
537 |
with gr.Row():
|
538 |
-
|
539 |
-
margin_opacity = gr.Slider(0,100,95,0.5,label="Margin Opacity %")
|
540 |
with gr.Row():
|
541 |
-
|
|
|
542 |
with gr.Row():
|
543 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
544 |
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
|
|
|
|
|
|
|
|
|
|
551 |
with gr.Row():
|
552 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
553 |
with gr.Row():
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
["assets//examples//hex_map_p1.png", False, True, -32,-31,80,80,-1.8,0,35,0,1,"#FFD0D0", 15],
|
559 |
-
["assets//examples//hex_map_p1_overlayed.png", False, False, -32,-31,80,80,-1.8,0,35,0,1,"#FFD0D0", 75],
|
560 |
-
["assets//examples//hex_flower_logo.png", False, True, -95,-95,100,100,-24,-2,190,30,2,"#FF8951", 50],
|
561 |
-
["assets//examples//hexed_fract_1.png", False, True, 0,0,0,0,0,0,10,0,0,"#000000", 5],
|
562 |
-
["assets//examples//tmpzt3mblvk.png", False, True, -20,10,0,0,-6,-2,35,30,1,"#ffffff", 0],
|
563 |
-
],
|
564 |
-
inputs=[input_image, filter_color, fill_hex, start_x, start_y, end_x, end_y, x_spacing, y_spacing, hex_size, rotation, border_size, border_color, border_opacity],
|
565 |
-
elem_id="examples")
|
566 |
-
with gr.Row():
|
567 |
-
gr.HTML(value=versions_html(), visible=True, elem_id="versions")
|
568 |
-
|
569 |
-
color_display.select(on_color_display_select,inputs=[color_display], outputs=[selected_row])
|
570 |
-
color_display.input(on_input,inputs=[color_display], outputs=[color_display, gr.State(excluded_color_list)])
|
571 |
-
|
572 |
-
delete_button.click(fn=delete_color, inputs=[selected_row, color_display], outputs=[color_display])
|
573 |
-
exclude_color_button.click(fn=add_color, inputs=[color_picker, gr.State(excluded_color_list)], outputs=[color_display, gr.State(excluded_color_list)])
|
574 |
-
hex_button.click(
|
575 |
-
fn=lambda hex_size, border_size, input_image, start_x, start_y, end_x, end_y, rotation, background_color, background_opacity, border_color, border_opacity, fill_hex, color_display, filter_color, x_spacing, y_spacing, add_hex_text, custom_text_list, custom_text_color_list:
|
576 |
-
gr.Warning("Please upload an Input Image to get started.") if input_image is None else hex_create(hex_size, border_size, input_image, start_x, start_y, end_x, end_y, rotation, background_color, background_opacity, border_color, border_opacity, fill_hex, color_display, filter_color, x_spacing, y_spacing, add_hex_text, custom_text_list, custom_text_color_list),
|
577 |
-
inputs=[hex_size, border_size, input_image, start_x, start_y, end_x, end_y, rotation, background_color, background_opacity, border_color, border_opacity, fill_hex, color_display, filter_color, x_spacing, y_spacing, add_hex_text, custom_text_list, custom_text_color_list],
|
578 |
-
outputs=[output_image, overlay_image],
|
579 |
-
scroll_to_output=True
|
580 |
-
)
|
581 |
-
generate_input_image.click(
|
582 |
-
fn=generate_input_image_click,
|
583 |
-
inputs=[map_options, prompt_textbox, negative_prompt_textbox, model_textbox,gr.State( seed if randomize_seed==False else random.randint(0, constants.MAX_SEED)), gr.State(False), gr.State(0.5), image_size_ratio],
|
584 |
-
outputs=[input_image], scroll_to_output=True
|
585 |
-
)
|
586 |
-
generate_depth_button.click(
|
587 |
-
fn=generate_depth_button_click,
|
588 |
-
inputs=[depth_image_source, voxel_size_factor, input_image, output_image, overlay_image, bordered_image_output],
|
589 |
-
outputs=[depth_map_output, model_output], scroll_to_output=True
|
590 |
-
)
|
591 |
-
model_textbox.change(
|
592 |
-
fn=update_prompt_notes,
|
593 |
-
inputs=model_textbox,
|
594 |
-
outputs=prompt_notes_label,preprocess=False
|
595 |
-
)
|
596 |
-
model_options.change(
|
597 |
-
fn=lambda x: (gr.update(visible=(x == "Manual Entry")), gr.update(value=x) if x != "Manual Entry" else gr.update()),
|
598 |
-
inputs=model_options,
|
599 |
-
outputs=[model_textbox, model_textbox]
|
600 |
-
)
|
601 |
-
model_options.change(
|
602 |
-
fn=update_prompt_notes,
|
603 |
-
inputs=model_options,
|
604 |
-
outputs=prompt_notes_label
|
605 |
-
)
|
606 |
-
composite_button.click(
|
607 |
-
fn=lambda input_image, composite_color, composite_opacity: gr.Warning("Please upload an Input Image to get started.") if input_image is None else change_color(input_image, composite_color, composite_opacity),
|
608 |
-
inputs=[input_image, composite_color, composite_opacity],
|
609 |
-
outputs=[input_image]
|
610 |
-
)
|
611 |
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
618 |
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
inputs=
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
657 |
beeuty.queue(default_concurrency_limit=1,max_size=12,api_open=False)
|
658 |
-
beeuty.launch(allowed_paths=["assets","/","./assets","images","./images", "./images/prerendered"], favicon_path="./assets/favicon.ico", max_file_size="10mb")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
# Import constants
|
3 |
+
import utils.constants as constants
|
4 |
import gradio as gr
|
5 |
from PIL import Image
|
6 |
from haishoku.haishoku import Haishoku
|
7 |
+
|
8 |
from tempfile import NamedTemporaryFile
|
9 |
#from pathlib import Path
|
10 |
import atexit
|
11 |
import random
|
12 |
+
import logging
|
|
|
13 |
|
14 |
IS_SHARED_SPACE = constants.IS_SHARED_SPACE
|
15 |
|
|
|
21 |
detect_color_format,
|
22 |
update_color_opacity,
|
23 |
)
|
24 |
+
from utils.misc import (get_filename, pause, convert_ratio_to_dimensions, install_cuda_toolkit,install_torch, _get_output, setup_runtime_env)
|
25 |
from utils.depth_estimation import estimate_depth, create_3d_model, generate_depth_and_3d, generate_depth_button_click
|
26 |
|
27 |
from utils.image_utils import (
|
|
|
34 |
show_lut,
|
35 |
apply_lut_to_image_path,
|
36 |
multiply_and_blend_images,
|
37 |
+
alpha_composite_with_control,
|
38 |
+
crop_and_resize_image
|
39 |
)
|
40 |
|
41 |
from utils.hex_grid import (
|
|
|
52 |
on_color_display_select
|
53 |
)
|
54 |
|
55 |
+
# from utils.ai_generator import (
|
56 |
+
# generate_ai_image,
|
57 |
+
# )
|
58 |
from utils.version_info import (
|
59 |
versions_html,
|
60 |
+
initialize_cuda,
|
61 |
+
release_torch_resources,
|
62 |
get_torch_info
|
63 |
)
|
64 |
from utils.lora_details import (
|
|
|
142 |
add_hex_text_option,
|
143 |
custom_text_list,
|
144 |
custom_text_color_list
|
145 |
+
)
|
|
|
146 |
return grid_image
|
147 |
|
148 |
def get_model_and_lora(model_textbox):
|
|
|
162 |
default_model = model_textbox
|
163 |
return default_model, []
|
164 |
|
165 |
+
|
166 |
+
def generate_input_image_click(map_option, prompt_textbox_value, negative_prompt_textbox_value, model_textbox_value, randomize_seed=True, seed=None, use_conditioned_image=False, strength=0.5, image_format="16:9", scale_factor=(8/3), progress=gr.Progress(track_tqdm=True)):
|
167 |
+
import spaces
|
168 |
+
from diffusers import FluxPipeline,FluxImg2ImgPipeline,FluxControlPipeline
|
169 |
+
import accelerate
|
170 |
+
from transformers import AutoTokenizer
|
171 |
+
from utils.lora_details import get_trigger_words, approximate_token_count, split_prompt_precisely
|
172 |
+
import gc
|
173 |
+
PIPELINE_CLASSES = {
|
174 |
+
"FluxPipeline": FluxPipeline,
|
175 |
+
"FluxImg2ImgPipeline": FluxImg2ImgPipeline,
|
176 |
+
"FluxControlPipeline": FluxControlPipeline
|
177 |
+
}
|
178 |
+
if randomize_seed:
|
179 |
+
seed = random.randint(0, constants.MAX_SEED)
|
180 |
+
|
181 |
+
@spaces.GPU(progress=gr.Progress(track_tqdm=True))
|
182 |
+
def generate_image_lowmem(
|
183 |
+
text,
|
184 |
+
neg_prompt=None,
|
185 |
+
model_name="black-forest-labs/FLUX.1-dev",
|
186 |
+
lora_weights=None,
|
187 |
+
conditioned_image=None,
|
188 |
+
image_width=1368,
|
189 |
+
image_height=848,
|
190 |
+
guidance_scale=3.5,
|
191 |
+
num_inference_steps=30,
|
192 |
+
seed=0,
|
193 |
+
true_cfg_scale=1.0,
|
194 |
+
pipeline_name="FluxPipeline",
|
195 |
+
strength=0.75,
|
196 |
+
additional_parameters=None,
|
197 |
+
progress=gr.Progress(track_tqdm=True)
|
198 |
+
):
|
199 |
+
from torch import cuda, bfloat16, float32, Generator, no_grad, backends
|
200 |
+
# Retrieve the pipeline class from the mapping
|
201 |
+
pipeline_class = PIPELINE_CLASSES.get(pipeline_name)
|
202 |
+
if not pipeline_class:
|
203 |
+
raise ValueError(f"Unsupported pipeline type '{pipeline_name}'. "
|
204 |
+
f"Available options: {list(PIPELINE_CLASSES.keys())}")
|
205 |
+
|
206 |
+
#initialize_cuda()
|
207 |
+
device = "cuda" if cuda.is_available() else "cpu"
|
208 |
+
from src.condition import Condition
|
209 |
+
|
210 |
+
print(f"device:{device}\nmodel_name:{model_name}\nlora_weights:{lora_weights}\n")
|
211 |
+
print(f"\n {get_torch_info()}\n")
|
212 |
+
# Disable gradient calculations
|
213 |
+
with no_grad():
|
214 |
+
# Initialize the pipeline inside the context manager
|
215 |
+
pipe = pipeline_class.from_pretrained(
|
216 |
+
model_name,
|
217 |
+
torch_dtype=bfloat16 if device == "cuda" else float32
|
218 |
+
).to(device)
|
219 |
+
# Optionally, don't use CPU offload if not necessary
|
220 |
+
|
221 |
+
# alternative version that may be more efficient
|
222 |
+
# pipe.enable_sequential_cpu_offload()
|
223 |
+
if pipeline_name == "FluxPipeline":
|
224 |
+
pipe.enable_model_cpu_offload()
|
225 |
+
pipe.vae.enable_slicing()
|
226 |
+
pipe.vae.enable_tiling()
|
227 |
+
else:
|
228 |
+
pipe.enable_model_cpu_offload()
|
229 |
+
|
230 |
+
# Access the tokenizer from the pipeline
|
231 |
+
tokenizer = pipe.tokenizer
|
232 |
+
|
233 |
+
# Check if add_prefix_space is set and convert to slow tokenizer if necessary
|
234 |
+
if getattr(tokenizer, 'add_prefix_space', False):
|
235 |
+
tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=False, device_map = 'cpu')
|
236 |
+
# Update the pipeline's tokenizer
|
237 |
+
pipe.tokenizer = tokenizer
|
238 |
+
pipe.to(device)
|
239 |
+
|
240 |
+
flash_attention_enabled = backends.cuda.flash_sdp_enabled()
|
241 |
+
if flash_attention_enabled == False:
|
242 |
+
#Enable xFormers memory-efficient attention (optional)
|
243 |
+
#pipe.enable_xformers_memory_efficient_attention()
|
244 |
+
print("\nEnabled xFormers memory-efficient attention.\n")
|
245 |
+
else:
|
246 |
+
pipe.attn_implementation="flash_attention_2"
|
247 |
+
print("\nEnabled flash_attention_2.\n")
|
248 |
+
|
249 |
+
condition_type = "subject"
|
250 |
+
# Load LoRA weights
|
251 |
+
# note: does not yet handle multiple LoRA weights with different names, needs .set_adapters(["depth", "hyper-sd"], adapter_weights=[0.85, 0.125])
|
252 |
+
if lora_weights:
|
253 |
+
for lora_weight in lora_weights:
|
254 |
+
lora_configs = constants.LORA_DETAILS.get(lora_weight, [])
|
255 |
+
lora_weight_set = False
|
256 |
+
if lora_configs:
|
257 |
+
for config in lora_configs:
|
258 |
+
# Load LoRA weights with optional weight_name and adapter_name
|
259 |
+
if 'weight_name' in config:
|
260 |
+
weight_name = config.get("weight_name")
|
261 |
+
adapter_name = config.get("adapter_name")
|
262 |
+
lora_collection = config.get("lora_collection")
|
263 |
+
if weight_name and adapter_name and lora_collection and lora_weight_set == False:
|
264 |
+
pipe.load_lora_weights(
|
265 |
+
lora_collection,
|
266 |
+
weight_name=weight_name,
|
267 |
+
adapter_name=adapter_name,
|
268 |
+
token=constants.HF_API_TOKEN
|
269 |
+
)
|
270 |
+
lora_weight_set = True
|
271 |
+
print(f"\npipe.load_lora_weights({lora_weight}, weight_name={weight_name}, adapter_name={adapter_name}, lora_collection={lora_collection}\n")
|
272 |
+
elif weight_name and adapter_name==None and lora_collection and lora_weight_set == False:
|
273 |
+
pipe.load_lora_weights(
|
274 |
+
lora_collection,
|
275 |
+
weight_name=weight_name,
|
276 |
+
token=constants.HF_API_TOKEN
|
277 |
+
)
|
278 |
+
lora_weight_set = True
|
279 |
+
print(f"\npipe.load_lora_weights({lora_weight}, weight_name={weight_name}, adapter_name={adapter_name}, lora_collection={lora_collection}\n")
|
280 |
+
elif weight_name and adapter_name and lora_weight_set == False:
|
281 |
+
pipe.load_lora_weights(
|
282 |
+
lora_weight,
|
283 |
+
weight_name=weight_name,
|
284 |
+
adapter_name=adapter_name,
|
285 |
+
token=constants.HF_API_TOKEN
|
286 |
+
)
|
287 |
+
lora_weight_set = True
|
288 |
+
print(f"\npipe.load_lora_weights({lora_weight}, weight_name={weight_name}, adapter_name={adapter_name}\n")
|
289 |
+
elif weight_name and adapter_name==None and lora_weight_set == False:
|
290 |
+
pipe.load_lora_weights(
|
291 |
+
lora_weight,
|
292 |
+
weight_name=weight_name,
|
293 |
+
token=constants.HF_API_TOKEN
|
294 |
+
)
|
295 |
+
lora_weight_set = True
|
296 |
+
print(f"\npipe.load_lora_weights({lora_weight}, weight_name={weight_name}, adapter_name={adapter_name}\n")
|
297 |
+
elif lora_weight_set == False:
|
298 |
+
pipe.load_lora_weights(
|
299 |
+
lora_weight,
|
300 |
+
token=constants.HF_API_TOKEN
|
301 |
+
)
|
302 |
+
lora_weight_set = True
|
303 |
+
print(f"\npipe.load_lora_weights({lora_weight}, weight_name={weight_name}, adapter_name={adapter_name}\n")
|
304 |
+
# Apply 'pipe' configurations if present
|
305 |
+
if 'pipe' in config:
|
306 |
+
pipe_config = config['pipe']
|
307 |
+
for method_name, params in pipe_config.items():
|
308 |
+
method = getattr(pipe, method_name, None)
|
309 |
+
if method:
|
310 |
+
print(f"Applying pipe method: {method_name} with params: {params}")
|
311 |
+
method(**params)
|
312 |
+
else:
|
313 |
+
print(f"Method {method_name} not found in pipe.")
|
314 |
+
if 'condition_type' in config:
|
315 |
+
condition_type = config['condition_type']
|
316 |
+
if condition_type == "coloring":
|
317 |
+
#pipe.enable_coloring()
|
318 |
+
print("\nEnabled coloring.\n")
|
319 |
+
elif condition_type == "deblurring":
|
320 |
+
#pipe.enable_deblurring()
|
321 |
+
print("\nEnabled deblurring.\n")
|
322 |
+
elif condition_type == "fill":
|
323 |
+
#pipe.enable_fill()
|
324 |
+
print("\nEnabled fill.\n")
|
325 |
+
elif condition_type == "depth":
|
326 |
+
#pipe.enable_depth()
|
327 |
+
print("\nEnabled depth.\n")
|
328 |
+
elif condition_type == "canny":
|
329 |
+
#pipe.enable_canny()
|
330 |
+
print("\nEnabled canny.\n")
|
331 |
+
elif condition_type == "subject":
|
332 |
+
#pipe.enable_subject()
|
333 |
+
print("\nEnabled subject.\n")
|
334 |
+
else:
|
335 |
+
print(f"Condition type {condition_type} not implemented.")
|
336 |
+
else:
|
337 |
+
pipe.load_lora_weights(lora_weight, use_auth_token=constants.HF_API_TOKEN)
|
338 |
+
# Set the random seed for reproducibility
|
339 |
+
generator = Generator(device=device).manual_seed(seed)
|
340 |
+
conditions = []
|
341 |
+
if conditioned_image is not None:
|
342 |
+
conditioned_image = crop_and_resize_image(conditioned_image, image_width, image_height)
|
343 |
+
condition = Condition(condition_type, conditioned_image)
|
344 |
+
conditions.append(condition)
|
345 |
+
print(f"\nAdded conditioned image.\n {conditioned_image.size}")
|
346 |
+
# Prepare the parameters for image generation
|
347 |
+
additional_parameters ={
|
348 |
+
"strength": strength,
|
349 |
+
"image": conditioned_image,
|
350 |
+
}
|
351 |
+
else:
|
352 |
+
print("\nNo conditioned image provided.")
|
353 |
+
if neg_prompt!=None:
|
354 |
+
true_cfg_scale=1.1
|
355 |
+
additional_parameters ={
|
356 |
+
"negative_prompt": neg_prompt,
|
357 |
+
"true_cfg_scale": true_cfg_scale,
|
358 |
+
}
|
359 |
+
# handle long prompts by splitting them
|
360 |
+
if approximate_token_count(text) > 76:
|
361 |
+
prompt, prompt2 = split_prompt_precisely(text)
|
362 |
+
prompt_parameters = {
|
363 |
+
"prompt" : prompt,
|
364 |
+
"prompt_2": prompt2
|
365 |
+
}
|
366 |
+
else:
|
367 |
+
prompt_parameters = {
|
368 |
+
"prompt" :text
|
369 |
+
}
|
370 |
+
additional_parameters.update(prompt_parameters)
|
371 |
+
# Combine all parameters
|
372 |
+
generate_params = {
|
373 |
+
"height": image_height,
|
374 |
+
"width": image_width,
|
375 |
+
"guidance_scale": guidance_scale,
|
376 |
+
"num_inference_steps": num_inference_steps,
|
377 |
+
"generator": generator, }
|
378 |
+
if additional_parameters:
|
379 |
+
generate_params.update(additional_parameters)
|
380 |
+
generate_params = {k: v for k, v in generate_params.items() if v is not None}
|
381 |
+
print(f"generate_params: {generate_params}")
|
382 |
+
# Generate the image
|
383 |
+
result = pipe(**generate_params)
|
384 |
+
image = result.images[0]
|
385 |
+
# Clean up
|
386 |
+
del result
|
387 |
+
del conditions
|
388 |
+
del generator
|
389 |
+
# Delete the pipeline and clear cache
|
390 |
+
del pipe
|
391 |
+
cuda.empty_cache()
|
392 |
+
cuda.ipc_collect()
|
393 |
+
print(cuda.memory_summary(device=None, abbreviated=False))
|
394 |
+
|
395 |
+
return image
|
396 |
+
|
397 |
+
#@spaces.GPU(progress=gr.Progress(track_tqdm=True))
|
398 |
+
def generate_ai_image_local (
|
399 |
+
map_option,
|
400 |
+
prompt_textbox_value,
|
401 |
+
neg_prompt_textbox_value,
|
402 |
+
model="black-forest-labs/FLUX.1-dev",
|
403 |
+
lora_weights=None,
|
404 |
+
conditioned_image=None,
|
405 |
+
height=512,
|
406 |
+
width=912,
|
407 |
+
num_inference_steps=30,
|
408 |
+
guidance_scale=3.5,
|
409 |
+
seed=777,
|
410 |
+
pipeline_name="FluxPipeline",
|
411 |
+
strength=0.75,
|
412 |
+
progress=gr.Progress(track_tqdm=True)
|
413 |
+
):
|
414 |
+
print(f"Generating image with lowmem")
|
415 |
+
try:
|
416 |
+
if map_option != "Prompt":
|
417 |
+
prompt = constants.PROMPTS[map_option]
|
418 |
+
negative_prompt = constants.NEGATIVE_PROMPTS.get(map_option, "")
|
419 |
+
else:
|
420 |
+
prompt = prompt_textbox_value
|
421 |
+
negative_prompt = neg_prompt_textbox_value or ""
|
422 |
+
#full_prompt = f"{prompt} {negative_prompt}"
|
423 |
+
additional_parameters = {}
|
424 |
+
if lora_weights:
|
425 |
+
for lora_weight in lora_weights:
|
426 |
+
lora_configs = constants.LORA_DETAILS.get(lora_weight, [])
|
427 |
+
for config in lora_configs:
|
428 |
+
if 'parameters' in config:
|
429 |
+
additional_parameters.update(config['parameters'])
|
430 |
+
elif 'trigger_words' in config:
|
431 |
+
trigger_words = get_trigger_words(lora_weight)
|
432 |
+
prompt = f"{trigger_words} {prompt}"
|
433 |
+
for key, value in additional_parameters.items():
|
434 |
+
if key in ['height', 'width', 'num_inference_steps', 'max_sequence_length']:
|
435 |
+
additional_parameters[key] = int(value)
|
436 |
+
elif key in ['guidance_scale','true_cfg_scale']:
|
437 |
+
additional_parameters[key] = float(value)
|
438 |
+
height = additional_parameters.pop('height', height)
|
439 |
+
width = additional_parameters.pop('width', width)
|
440 |
+
num_inference_steps = additional_parameters.pop('num_inference_steps', num_inference_steps)
|
441 |
+
guidance_scale = additional_parameters.pop('guidance_scale', guidance_scale)
|
442 |
+
print("Generating image with the following parameters:")
|
443 |
+
print(f"Model: {model}")
|
444 |
+
print(f"LoRA Weights: {lora_weights}")
|
445 |
+
print(f"Prompt: {prompt}")
|
446 |
+
print(f"Neg Prompt: {negative_prompt}")
|
447 |
+
print(f"Height: {height}")
|
448 |
+
print(f"Width: {width}")
|
449 |
+
print(f"Number of Inference Steps: {num_inference_steps}")
|
450 |
+
print(f"Guidance Scale: {guidance_scale}")
|
451 |
+
print(f"Seed: {seed}")
|
452 |
+
print(f"Additional Parameters: {additional_parameters}")
|
453 |
+
print(f"Conditioned Image: {conditioned_image}")
|
454 |
+
print(f"Conditioned Image Strength: {strength}")
|
455 |
+
print(f"pipeline: {pipeline_name}")
|
456 |
+
image = generate_image_lowmem(
|
457 |
+
text=prompt,
|
458 |
+
model_name=model,
|
459 |
+
neg_prompt=negative_prompt,
|
460 |
+
lora_weights=lora_weights,
|
461 |
+
conditioned_image=conditioned_image,
|
462 |
+
image_width=width,
|
463 |
+
image_height=height,
|
464 |
+
guidance_scale=guidance_scale,
|
465 |
+
num_inference_steps=num_inference_steps,
|
466 |
+
seed=seed,
|
467 |
+
pipeline_name=pipeline_name,
|
468 |
+
strength=strength,
|
469 |
+
additional_parameters=additional_parameters
|
470 |
+
)
|
471 |
+
with NamedTemporaryFile(delete=False, suffix=".png") as tmp:
|
472 |
+
image.save(tmp.name, format="PNG")
|
473 |
+
constants.temp_files.append(tmp.name)
|
474 |
+
print(f"Image saved to {tmp.name}")
|
475 |
+
release_torch_resources()
|
476 |
+
gc.collect()
|
477 |
+
return tmp.name
|
478 |
+
except Exception as e:
|
479 |
+
print(f"Error generating AI image: {e}")
|
480 |
+
release_torch_resources()
|
481 |
+
gc.collect()
|
482 |
+
return None
|
483 |
# Get the model and LoRA weights
|
484 |
model, lora_weights = get_model_and_lora(model_textbox_value)
|
485 |
global current_prerendered_image
|
|
|
488 |
if use_conditioned_image:
|
489 |
print(f"Conditioned path: {current_prerendered_image.value}.. converting to RGB\n")
|
490 |
# ensure the conditioned image is an image and not a string, cannot use RGBA
|
491 |
+
if isinstance(current_prerendered_image.value, str):
|
492 |
conditioned_image = open_image(current_prerendered_image.value).convert("RGB")
|
493 |
print(f"Conditioned Image: {conditioned_image.size}.. converted to RGB\n")
|
494 |
|
|
|
496 |
width_ratio, height_ratio = map(int, image_format.split(":"))
|
497 |
aspect_ratio = width_ratio / height_ratio
|
498 |
|
499 |
+
width, height = convert_ratio_to_dimensions(aspect_ratio, 576)
|
500 |
+
pipeline = "FluxPipeline"
|
501 |
+
if conditioned_image is not None:
|
502 |
+
pipeline = "FluxImg2ImgPipeline"
|
503 |
# Generate the AI image and get the image path
|
504 |
+
image_path = generate_ai_image_local(
|
505 |
map_option,
|
506 |
prompt_textbox_value,
|
507 |
negative_prompt_textbox_value,
|
508 |
model,
|
509 |
lora_weights,
|
510 |
conditioned_image,
|
511 |
+
strength=strength,
|
512 |
height=height,
|
513 |
width=width,
|
514 |
+
seed=seed,
|
515 |
+
pipeline_name=pipeline,
|
516 |
)
|
517 |
|
518 |
# Open the generated image
|
|
|
530 |
upscaled_image.save(tmp_upscaled.name, format="PNG")
|
531 |
constants.temp_files.append(tmp_upscaled.name)
|
532 |
print(f"Upscaled image saved to {tmp_upscaled.name}")
|
533 |
+
|
534 |
# Return the path of the upscaled image
|
535 |
return tmp_upscaled.name
|
536 |
|
|
|
559 |
print(f"Combining images with alpha: {alpha}")
|
560 |
return lerp_imagemath(in_image, out_image, alpha)
|
561 |
|
562 |
+
def add_border(image, mask_width, mask_height, blank_color):
|
563 |
+
#install_torch()
|
564 |
bordered_image_output = Image.open(image).convert("RGBA")
|
565 |
margin_color = detect_color_format(blank_color)
|
566 |
print(f"Adding border to image with width: {mask_width}, height: {mask_height}, color: {margin_color}")
|
567 |
return shrink_and_paste_on_blank(bordered_image_output, mask_width, mask_height, margin_color)
|
568 |
+
def main(debug):
|
569 |
+
title = "HexaGrid Creator"
|
570 |
+
#description = "Customizable Hexagon Grid Image Generator"
|
571 |
+
examples = [["assets//examples//hex_map_p1.png", 32, 1, 0, 0, 0, 0, 0, "#ede9ac44","#12165380", True]]
|
572 |
|
573 |
+
gr.set_static_paths(paths=["images/","images/images","images/prerendered","LUT/","fonts/"])
|
|
|
|
|
574 |
|
575 |
+
# Gradio Blocks Interface
|
576 |
+
with gr.Blocks(css_paths="style_20250128.css", title=title, theme='Surn/beeuty') as beeuty:
|
577 |
+
with gr.Row():
|
578 |
+
gr.Markdown("""
|
579 |
+
# HexaGrid Creator
|
580 |
+
## Transform Your Images into Mesmerizing Hexagon Grid Masterpieces! ⬢""", elem_classes="intro")
|
581 |
+
with gr.Row():
|
582 |
+
with gr.Accordion("Welcome to HexaGrid Creator, the ultimate tool for transforming your images into stunning hexagon grid artworks. Whether you're a tabletop game enthusiast, a digital artist, or someone who loves unique patterns, HexaGrid Creator has something for you.", open=False, elem_classes="intro"):
|
583 |
+
gr.Markdown ("""
|
|
|
584 |
|
585 |
+
## Drop an image into the Input Image and get started!
|
586 |
|
587 |
|
588 |
|
589 |
+
## What is HexaGrid Creator?
|
590 |
+
HexaGrid Creator is a web-based application that allows you to apply a hexagon grid overlay to any image. You can customize the size, color, and opacity of the hexagons, as well as the background and border colors. The result is a visually striking image that looks like it was made from hexagonal tiles!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
591 |
|
592 |
+
### What Can You Do?
|
593 |
+
- **Generate Hexagon Grids:** Create beautiful hexagon grid overlays on any image with fully customizable parameters.
|
594 |
+
- **AI-Powered Image Generation:** Use advanced AI models to generate images based on your prompts and apply hexagon grids to them.
|
595 |
+
- **Color Exclusion:** Select and exclude specific colors from your hexagon grid for a cleaner and more refined look.
|
596 |
+
- **Interactive Customization:** Adjust hexagon size, border size, rotation, background color, and more in real-time.
|
597 |
+
- **Depth and 3D Model Generation:** Generate depth maps and 3D models from your images for enhanced visualization.
|
598 |
+
- **Image Filter [Look-Up Table (LUT)] Application:** Apply filters (LUTs) to your images for color grading and enhancement.
|
599 |
+
- **Pre-rendered Maps:** Access a library of pre-rendered hexagon maps for quick and easy customization.
|
600 |
+
- **Add Margins:** Add customizable margins around your images for a polished finish.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
601 |
|
602 |
+
### Why You'll Love It
|
603 |
+
- **Fun and Easy to Use:** With an intuitive interface and real-time previews, creating hexagon grids has never been this fun!
|
604 |
+
- **Endless Creativity:** Unleash your creativity with endless customization options and see your images transform in unique ways.
|
605 |
+
- **Hexagon-Inspired Theme:** Enjoy a delightful yellow and purple theme inspired by hexagons! ⬢
|
606 |
+
- **Advanced AI Models:** Leverage advanced AI models and LoRA weights for high-quality image generation and customization.
|
607 |
+
|
608 |
+
### Get Started
|
609 |
+
1. **Upload or Generate an Image:** Start by uploading your own image or generate one using our AI-powered tool.
|
610 |
+
2. **Customize Your Grid:** Play around with the settings to create the perfect hexagon grid overlay.
|
611 |
+
3. **Download and Share:** Once you're happy with your creation, download it and share it with the world!
|
612 |
+
|
613 |
+
### Advanced Features
|
614 |
+
- **Generative AI Integration:** Utilize models like `black-forest-labs/FLUX.1-dev` and various LoRA weights for generating unique images.
|
615 |
+
- **Pre-rendered Maps:** Access a library of pre-rendered hexagon maps for quick and easy customization.
|
616 |
+
- **Image Filter [Look-Up Table (LUT)] Application:** Apply filters (LUTs) to your images for color grading and enhancement.
|
617 |
+
- **Depth and 3D Model Generation:** Create depth maps and 3D models from your images for enhanced visualization.
|
618 |
+
- **Add Margins:** Customize margins around your images for a polished finish.
|
619 |
+
|
620 |
+
Join the hive and start creating with HexaGrid Creator today!
|
621 |
+
|
622 |
+
""", elem_classes="intro")
|
623 |
+
with gr.Row():
|
624 |
+
from utils.image_utils import convert_to_rgba_png
|
625 |
+
|
626 |
+
# Existing code
|
627 |
+
with gr.Column(scale=2):
|
628 |
+
input_image = gr.Image(
|
629 |
+
label="Input Image",
|
630 |
+
type="filepath",
|
631 |
+
interactive=True,
|
632 |
+
elem_classes="centered solid imgcontainer",
|
633 |
+
key="imgInput",
|
634 |
+
image_mode=None,
|
635 |
+
format="PNG",
|
636 |
+
show_download_button=True,
|
637 |
)
|
638 |
|
639 |
+
# New code to convert input image to RGBA PNG
|
640 |
+
def on_input_image_change(image_path):
|
641 |
+
if image_path is None:
|
642 |
+
gr.Warning("Please upload an Input Image to get started.")
|
643 |
+
return None
|
644 |
+
img, img_path = convert_to_rgba_png(image_path)
|
645 |
+
return img_path
|
646 |
+
|
647 |
+
input_image.change(
|
648 |
+
fn=on_input_image_change,
|
649 |
+
inputs=[input_image],
|
650 |
+
outputs=[input_image], scroll_to_output=True,
|
651 |
+
)
|
652 |
+
with gr.Column():
|
653 |
+
with gr.Accordion("Hex Coloring and Exclusion", open = False):
|
|
|
|
|
|
|
654 |
with gr.Row():
|
655 |
with gr.Column():
|
656 |
+
color_picker = gr.ColorPicker(label="Pick a color to exclude",value="#505050")
|
657 |
+
with gr.Column():
|
658 |
+
filter_color = gr.Checkbox(label="Filter Excluded Colors from Sampling", value=False,)
|
659 |
+
exclude_color_button = gr.Button("Exclude Color", elem_id="exlude_color_button", elem_classes="solid")
|
660 |
+
color_display = gr.DataFrame(label="List of Excluded RGBA Colors", headers=["R", "G", "B", "A"], elem_id="excluded_colors", type="array", value=build_dataframe(excluded_color_list), interactive=True, elem_classes="solid centered")
|
661 |
+
selected_row = gr.Number(0, label="Selected Row", visible=False)
|
662 |
+
delete_button = gr.Button("Delete Row", elem_id="delete_exclusion_button", elem_classes="solid")
|
663 |
+
fill_hex = gr.Checkbox(label="Fill Hex with color from Image", value=True)
|
664 |
+
with gr.Accordion("Image Filters", open = False):
|
665 |
+
with gr.Row():
|
666 |
+
with gr.Column():
|
667 |
+
composite_color = gr.ColorPicker(label="Color", value="#ede9ac44")
|
668 |
+
with gr.Column():
|
669 |
+
composite_opacity = gr.Slider(label="Opacity %", minimum=0, maximum=100, value=50, interactive=True)
|
670 |
+
with gr.Row():
|
671 |
+
composite_button = gr.Button("Composite", elem_classes="solid")
|
672 |
+
with gr.Row():
|
673 |
+
with gr.Column():
|
674 |
+
lut_filename = gr.Textbox(
|
675 |
+
value="",
|
676 |
+
label="Look Up Table (LUT) File Name",
|
677 |
+
elem_id="lutFileName")
|
678 |
+
with gr.Column():
|
679 |
+
lut_file = gr.File(
|
680 |
+
value=None,
|
681 |
+
file_count="single",
|
682 |
+
file_types=[".cube"],
|
683 |
+
type="filepath",
|
684 |
+
label="LUT cube File")
|
685 |
+
with gr.Row():
|
686 |
+
lut_example_image = gr.Image(type="pil", label="Filter (LUT) Example Image", value=constants.default_lut_example_img)
|
687 |
+
with gr.Row():
|
688 |
with gr.Column():
|
689 |
+
gr.Markdown("""
|
690 |
+
### Included Filters (LUTs)
|
691 |
+
There are several included Filters:
|
692 |
+
|
693 |
+
Try them on the example image before applying to your Input Image.
|
694 |
+
""", elem_id="lut_markdown")
|
695 |
with gr.Column():
|
696 |
+
gr.Examples(elem_id="lut_examples",
|
697 |
+
examples=[[f] for f in constants.lut_files],
|
698 |
+
inputs=[lut_filename],
|
699 |
+
outputs=[lut_filename],
|
700 |
+
label="Select a Filter (LUT) file. Populate the LUT File Name field"
|
|
|
|
|
701 |
)
|
702 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
703 |
with gr.Row():
|
704 |
+
apply_lut_button = gr.Button("Apply Filter (LUT)", elem_classes="solid", elem_id="apply_lut_button")
|
705 |
+
|
706 |
+
lut_file.change(get_filename, inputs=[lut_file], outputs=[lut_filename])
|
707 |
+
lut_filename.change(show_lut, inputs=[lut_filename, lut_example_image], outputs=[lut_example_image])
|
708 |
+
apply_lut_button.click(
|
709 |
+
lambda lut_filename, input_image: gr.Warning("Please upload an Input Image to get started.") if input_image is None else apply_lut_to_image_path(lut_filename, input_image)[0],
|
710 |
+
inputs=[lut_filename, input_image],
|
711 |
+
outputs=[input_image],
|
712 |
+
scroll_to_output=True
|
713 |
)
|
714 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
715 |
with gr.Row():
|
716 |
+
with gr.Accordion("Generative AI", open = False):
|
717 |
+
with gr.Row():
|
718 |
+
with gr.Column():
|
719 |
+
model_options = gr.Dropdown(
|
720 |
+
label="Model Options",
|
721 |
+
choices=constants.MODELS + constants.LORA_WEIGHTS + ["Manual Entry"],
|
722 |
+
value="Cossale/Frames2-Flex.1",
|
723 |
+
elem_classes="solid"
|
724 |
+
)
|
725 |
+
model_textbox = gr.Textbox(
|
726 |
+
label="LORA/Model",
|
727 |
+
value="Cossale/Frames2-Flex.1",
|
728 |
+
elem_classes="solid",
|
729 |
+
elem_id="inference_model",
|
730 |
+
visible=False
|
731 |
+
)
|
732 |
+
# Update map_options to a Dropdown with choices from constants.PROMPTS keys
|
733 |
+
with gr.Row():
|
734 |
+
with gr.Column():
|
735 |
+
map_options = gr.Dropdown(
|
736 |
+
label="Map Options",
|
737 |
+
choices=list(constants.PROMPTS.keys()),
|
738 |
+
value="Alien Landscape",
|
739 |
+
elem_classes="solid",
|
740 |
+
scale=0
|
741 |
+
)
|
742 |
+
with gr.Column():
|
743 |
+
# Add Dropdown for sizing of Images, height and width based on selection. Options are 16x9, 16x10, 4x5, 1x1
|
744 |
+
# The values of height and width are based on common resolutions for each aspect ratio
|
745 |
+
# Default to 16x9, 912x512
|
746 |
+
image_size_ratio = gr.Dropdown(label="Image Size", choices=["16:9", "16:10", "4:5", "4:3", "2:1","3:2","1:1", "9:16", "10:16", "5:4", "3:4","1:2", "2:3"], value="16:9", elem_classes="solid", type="value", scale=0, interactive=True)
|
747 |
+
with gr.Column():
|
748 |
+
seed_slider = gr.Slider(
|
749 |
+
label="Seed",
|
750 |
+
minimum=0,
|
751 |
+
maximum=constants.MAX_SEED,
|
752 |
+
step=1,
|
753 |
+
value=0,
|
754 |
+
scale=0
|
755 |
+
)
|
756 |
+
randomize_seed = gr.Checkbox(label="Randomize seed", value=True, scale=0, interactive=True)
|
757 |
+
prompt_textbox = gr.Textbox(
|
758 |
+
label="Prompt",
|
759 |
+
visible=False,
|
760 |
+
elem_classes="solid",
|
761 |
+
value="top-down, (rectangular tabletop_map) alien planet map, Battletech_boardgame scifi world with forests, lakes, oceans, continents and snow at the top and bottom, (middle is dark, no_reflections, no_shadows), from directly above. From 100,000 feet looking straight down",
|
762 |
+
lines=4
|
763 |
+
)
|
764 |
+
negative_prompt_textbox = gr.Textbox(
|
765 |
+
label="Negative Prompt",
|
766 |
+
visible=False,
|
767 |
+
elem_classes="solid",
|
768 |
+
value="Earth, low quality, bad anatomy, blurry, cropped, worst quality, shadows, people, humans, reflections, shadows, realistic map of the Earth, isometric, text"
|
769 |
+
)
|
770 |
+
prompt_notes_label = gr.Label(
|
771 |
+
"You should use FRM$ as trigger words. @1.5 minutes",
|
772 |
+
elem_classes="solid centered small",
|
773 |
+
show_label=False,
|
774 |
+
visible=False
|
775 |
+
)
|
776 |
+
# Keep the change event to maintain functionality
|
777 |
+
map_options.change(
|
778 |
+
fn=update_prompt_visibility,
|
779 |
+
inputs=[map_options],
|
780 |
+
outputs=[prompt_textbox, negative_prompt_textbox, prompt_notes_label]
|
781 |
+
)
|
782 |
+
with gr.Row():
|
783 |
+
generate_input_image = gr.Button(
|
784 |
+
"Generate AI Image",
|
785 |
+
elem_id="generate_input_image",
|
786 |
+
elem_classes="solid"
|
787 |
+
)
|
788 |
+
with gr.Column(scale=2):
|
789 |
+
with gr.Accordion("Template Image Styles", open = False):
|
790 |
+
with gr.Row():
|
791 |
+
# Gallery from PRE_RENDERED_IMAGES GOES HERE
|
792 |
+
prerendered_image_gallery = gr.Gallery(label="Image Gallery", show_label=True, value=build_prerendered_images(constants.pre_rendered_maps_paths), elem_id="gallery", elem_classes="solid", type="filepath", columns=[3], rows=[3], preview=False ,object_fit="contain", height="auto", format="png",allow_preview=False)
|
793 |
+
with gr.Row():
|
794 |
+
image_guidance_stength = gr.Slider(label="Image Guidance Strength", minimum=0, maximum=1.0, value=0.25, step=0.01, interactive=True)
|
795 |
+
with gr.Column():
|
796 |
+
replace_input_image_button = gr.Button(
|
797 |
+
"Replace Input Image",
|
798 |
+
elem_id="prerendered_replace_input_image_button",
|
799 |
+
elem_classes="solid"
|
800 |
+
)
|
801 |
+
with gr.Column():
|
802 |
+
generate_input_image_from_gallery = gr.Button(
|
803 |
+
"Generate AI Image from Gallery",
|
804 |
+
elem_id="generate_input_image_from_gallery",
|
805 |
+
elem_classes="solid"
|
806 |
+
)
|
807 |
+
|
808 |
+
with gr.Accordion("Advanced Hexagon Settings", open = False):
|
809 |
+
with gr.Row():
|
810 |
+
start_x = gr.Number(label="Start X", value=0, minimum=-512, maximum= 512, precision=0)
|
811 |
+
start_y = gr.Number(label="Start Y", value=0, minimum=-512, maximum= 512, precision=0)
|
812 |
+
end_x = gr.Number(label="End X", value=0, minimum=-512, maximum= 512, precision=0)
|
813 |
+
end_y = gr.Number(label="End Y", value=0, minimum=-512, maximum= 512, precision=0)
|
814 |
+
with gr.Row():
|
815 |
+
x_spacing = gr.Number(label="Adjust Horizontal spacing", value=-1, minimum=-200, maximum=200, precision=1)
|
816 |
+
y_spacing = gr.Number(label="Adjust Vertical spacing", value=1, minimum=-200, maximum=200, precision=1)
|
817 |
+
with gr.Row():
|
818 |
+
rotation = gr.Slider(-90, 180, 0.0, 0.1, label="Hexagon Rotation (degree)")
|
819 |
+
add_hex_text = gr.Dropdown(label="Add Text to Hexagons", choices=[None, "Row-Column Coordinates", "Sequential Numbers", "Playing Cards Sequential", "Playing Cards Alternate Red and Black", "Custom List"], value=None)
|
820 |
+
with gr.Row():
|
821 |
+
custom_text_list = gr.TextArea(label="Custom Text List", value=constants.cards_alternating, visible=False,)
|
822 |
+
custom_text_color_list = gr.TextArea(label="Custom Text Color List", value=constants.card_colors_alternating, visible=False)
|
823 |
+
with gr.Row():
|
824 |
+
hex_text_info = gr.Markdown("""
|
825 |
+
### Text Color uses the Border Color and Border Opacity, unless you use a custom list.
|
826 |
+
### The Custom Text List and Custom Text Color List are comma separated lists.
|
827 |
+
### The custom color list is a comma separated list of hex colors.
|
828 |
+
#### Example: "A,2,3,4,5,6,7,8,9,10,J,Q,K", "red,#0000FF,#00FF00,red,#FFFF00,#00FFFF,#FF8000,#FF00FF,#FF0080,#FF8000,#FF0080,lightblue"
|
829 |
+
""", elem_id="hex_text_info", visible=False)
|
830 |
+
add_hex_text.change(
|
831 |
+
fn=lambda x: (
|
832 |
+
gr.update(visible=(x == "Custom List")),
|
833 |
+
gr.update(visible=(x == "Custom List")),
|
834 |
+
gr.update(visible=(x != None))
|
835 |
+
),
|
836 |
+
inputs=add_hex_text,
|
837 |
+
outputs=[custom_text_list, custom_text_color_list, hex_text_info]
|
838 |
+
)
|
839 |
with gr.Row():
|
840 |
+
hex_size = gr.Number(label="Hexagon Size", value=32, minimum=1, maximum=768)
|
841 |
+
border_size = gr.Slider(-5,25,value=0,step=1,label="Border Size")
|
842 |
+
with gr.Row():
|
843 |
+
background_color = gr.ColorPicker(label="Background Color", value="#000000", interactive=True)
|
844 |
+
background_opacity = gr.Slider(0,100,0,1,label="Background Opacity %")
|
845 |
+
border_color = gr.ColorPicker(label="Border Color", value="#7b7b7b", interactive=True)
|
846 |
+
border_opacity = gr.Slider(0,100,0,1,label="Border Opacity %")
|
847 |
with gr.Row():
|
848 |
+
hex_button = gr.Button("Generate Hex Grid!", elem_classes="solid", elem_id="btn-generate")
|
|
|
849 |
with gr.Row():
|
850 |
+
output_image = gr.Image(label="Hexagon Grid Image", image_mode = "RGBA", show_download_button=True, show_share_button=True,elem_classes="centered solid imgcontainer", format="PNG", type="filepath", key="ImgOutput")
|
851 |
+
overlay_image = gr.Image(label="Hexagon Overlay Image", image_mode = "RGBA", show_share_button=True, elem_classes="centered solid imgcontainer", format="PNG", type="filepath", key="ImgOverlay")
|
852 |
with gr.Row():
|
853 |
+
output_overlay_composite = gr.Slider(0,100,50,0.5, label="Interpolate Intensity")
|
854 |
+
output_blend_multiply_composite = gr.Slider(0,100,50,0.5, label="Overlay Intensity")
|
855 |
+
output_alpha_composite = gr.Slider(0,100,50,0.5, label="Alpha Composite Intensity")
|
856 |
+
with gr.Accordion("Add Margins (bleed)", open=False):
|
857 |
+
with gr.Row():
|
858 |
+
border_image_source = gr.Radio(label="Add Margins around which Image", choices=["Input Image", "Overlay Image"], value="Overlay Image")
|
859 |
+
with gr.Row():
|
860 |
+
mask_width = gr.Number(label="Margins Width", value=10, minimum=0, maximum=100, precision=0)
|
861 |
+
mask_height = gr.Number(label="Margins Height", value=10, minimum=0, maximum=100, precision=0)
|
862 |
+
with gr.Row():
|
863 |
+
margin_color = gr.ColorPicker(label="Margin Color", value="#333333FF", interactive=True)
|
864 |
+
margin_opacity = gr.Slider(0,100,95,0.5,label="Margin Opacity %")
|
865 |
+
with gr.Row():
|
866 |
+
add_border_button = gr.Button("Add Margins", elem_classes="solid", variant="secondary")
|
867 |
+
with gr.Row():
|
868 |
+
bordered_image_output = gr.Image(label="Image with Margins", image_mode="RGBA", show_download_button=True, show_share_button=True, elem_classes="centered solid imgcontainer", format="PNG", type="filepath", key="ImgBordered")
|
869 |
|
870 |
+
with gr.Accordion("Height Maps and 3D", open = False):
|
871 |
+
with gr.Row():
|
872 |
+
with gr.Column():
|
873 |
+
voxel_size_factor = gr.Slider(label="Voxel Size Factor", value=1.00, minimum=0.01, maximum=40.00, step=0.01)
|
874 |
+
with gr.Column():
|
875 |
+
depth_image_source = gr.Radio(label="Depth Image Source", choices=["Input Image", "Output Image", "Overlay Image","Image with Margins"], value="Input Image")
|
876 |
+
with gr.Row():
|
877 |
+
generate_depth_button = gr.Button("Generate Depth Map and 3D Model From Selected Image", elem_classes="solid", variant="secondary")
|
878 |
+
with gr.Row():
|
879 |
+
depth_map_output = gr.Image(label="Depth Map", image_mode="L", elem_classes="centered solid imgcontainer", format="PNG", type="filepath", key="ImgDepth")
|
880 |
+
model_output = gr.Model3D(label="3D Model", clear_color=[1.0, 1.0, 1.0, 0.25], key="Img3D", elem_classes="centered solid imgcontainer")
|
881 |
with gr.Row():
|
882 |
+
gr.Examples(examples=[
|
883 |
+
["assets//examples//hex_map_p1.png", False, True, -32,-31,80,80,-1.8,0,35,0,1,"#FFD0D0", 15],
|
884 |
+
["assets//examples//hex_map_p1_overlayed.png", False, False, -32,-31,80,80,-1.8,0,35,0,1,"#FFD0D0", 75],
|
885 |
+
["assets//examples//hex_flower_logo.png", False, True, -95,-95,100,100,-24,-2,190,30,2,"#FF8951", 50],
|
886 |
+
["assets//examples//hexed_fract_1.png", False, True, 0,0,0,0,0,0,10,0,0,"#000000", 5],
|
887 |
+
["assets//examples//tmpzt3mblvk.png", False, True, -20,10,0,0,-6,-2,35,30,1,"#ffffff", 0],
|
888 |
+
],
|
889 |
+
inputs=[input_image, filter_color, fill_hex, start_x, start_y, end_x, end_y, x_spacing, y_spacing, hex_size, rotation, border_size, border_color, border_opacity],
|
890 |
+
elem_id="examples")
|
891 |
+
#with gr.Row():
|
892 |
+
#gr.HTML(value=versions_html(), visible=True, elem_id="versions")
|
893 |
with gr.Row():
|
894 |
+
reinstall_torch = gr.Button("Reinstall Torch", elem_classes="solid small", variant="secondary")
|
895 |
+
reinstall_cuda_toolkit = gr.Button("Install CUDA Toolkit", elem_classes="solid small", variant="secondary")
|
896 |
+
reinitialize_cuda = gr.Button("Reinitialize CUDA", elem_classes="solid small", variant="secondary")
|
897 |
+
torch_release = gr.Button("Release Torch Resources", elem_classes="solid small", variant="secondary")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
898 |
|
899 |
+
reinitialize_cuda.click(
|
900 |
+
fn=initialize_cuda,
|
901 |
+
inputs=[],
|
902 |
+
outputs=[]
|
903 |
+
)
|
904 |
+
torch_release.click(
|
905 |
+
fn=release_torch_resources,
|
906 |
+
inputs=[],
|
907 |
+
outputs=[]
|
908 |
+
)
|
909 |
+
reinstall_torch.click(
|
910 |
+
fn=install_torch,
|
911 |
+
inputs=[],
|
912 |
+
outputs=[]
|
913 |
+
)
|
914 |
|
915 |
+
reinstall_cuda_toolkit.click(
|
916 |
+
fn=install_cuda_toolkit,
|
917 |
+
inputs=[],
|
918 |
+
outputs=[]
|
919 |
+
)
|
920 |
+
|
921 |
+
color_display.select(on_color_display_select,inputs=[color_display], outputs=[selected_row])
|
922 |
+
color_display.input(on_input,inputs=[color_display], outputs=[color_display, gr.State(excluded_color_list)])
|
923 |
+
|
924 |
+
delete_button.click(fn=delete_color, inputs=[selected_row, color_display], outputs=[color_display])
|
925 |
+
exclude_color_button.click(fn=add_color, inputs=[color_picker, gr.State(excluded_color_list)], outputs=[color_display, gr.State(excluded_color_list)])
|
926 |
+
hex_button.click(
|
927 |
+
fn=lambda hex_size, border_size, input_image, start_x, start_y, end_x, end_y, rotation, background_color, background_opacity, border_color, border_opacity, fill_hex, color_display, filter_color, x_spacing, y_spacing, add_hex_text, custom_text_list, custom_text_color_list:
|
928 |
+
gr.Warning("Please upload an Input Image to get started.") if input_image is None else hex_create(hex_size, border_size, input_image, start_x, start_y, end_x, end_y, rotation, background_color, background_opacity, border_color, border_opacity, fill_hex, color_display, filter_color, x_spacing, y_spacing, add_hex_text, custom_text_list, custom_text_color_list),
|
929 |
+
inputs=[hex_size, border_size, input_image, start_x, start_y, end_x, end_y, rotation, background_color, background_opacity, border_color, border_opacity, fill_hex, color_display, filter_color, x_spacing, y_spacing, add_hex_text, custom_text_list, custom_text_color_list],
|
930 |
+
outputs=[output_image, overlay_image],
|
931 |
+
scroll_to_output=True
|
932 |
+
)
|
933 |
+
generate_input_image.click(
|
934 |
+
fn=generate_input_image_click,
|
935 |
+
inputs=[map_options, prompt_textbox, negative_prompt_textbox, model_textbox, randomize_seed, seed_slider, gr.State(False), gr.State(0.5), image_size_ratio],
|
936 |
+
outputs=[input_image], scroll_to_output=True
|
937 |
+
)
|
938 |
+
generate_depth_button.click(
|
939 |
+
fn=generate_depth_button_click,
|
940 |
+
inputs=[depth_image_source, voxel_size_factor, input_image, output_image, overlay_image, bordered_image_output],
|
941 |
+
outputs=[depth_map_output, model_output], scroll_to_output=True
|
942 |
+
)
|
943 |
+
model_textbox.change(
|
944 |
+
fn=update_prompt_notes,
|
945 |
+
inputs=model_textbox,
|
946 |
+
outputs=prompt_notes_label,preprocess=False
|
947 |
+
)
|
948 |
+
model_options.change(
|
949 |
+
fn=lambda x: (gr.update(visible=(x == "Manual Entry")), gr.update(value=x) if x != "Manual Entry" else gr.update()),
|
950 |
+
inputs=model_options,
|
951 |
+
outputs=[model_textbox, model_textbox]
|
952 |
+
)
|
953 |
+
model_options.change(
|
954 |
+
fn=update_prompt_notes,
|
955 |
+
inputs=model_options,
|
956 |
+
outputs=prompt_notes_label
|
957 |
+
)
|
958 |
+
composite_button.click(
|
959 |
+
fn=lambda input_image, composite_color, composite_opacity: gr.Warning("Please upload an Input Image to get started.") if input_image is None else change_color(input_image, composite_color, composite_opacity),
|
960 |
+
inputs=[input_image, composite_color, composite_opacity],
|
961 |
+
outputs=[input_image]
|
962 |
+
)
|
963 |
+
|
964 |
+
#use conditioned_image as the input_image for generate_input_image_click
|
965 |
+
generate_input_image_from_gallery.click(
|
966 |
+
fn=generate_input_image_click,
|
967 |
+
inputs=[map_options, prompt_textbox, negative_prompt_textbox, model_textbox,randomize_seed, seed_slider, gr.State(True), image_guidance_stength, image_size_ratio],
|
968 |
+
outputs=[input_image], scroll_to_output=True
|
969 |
+
)
|
970 |
+
|
971 |
+
# Update the state variable with the prerendered image filepath when an image is selected
|
972 |
+
prerendered_image_gallery.select(
|
973 |
+
fn=on_prerendered_gallery_selection,
|
974 |
+
inputs=None,
|
975 |
+
outputs=[gr.State(current_prerendered_image)], # Update the state with the selected image
|
976 |
+
show_api=False
|
977 |
+
)
|
978 |
+
# replace input image with selected gallery image
|
979 |
+
replace_input_image_button.click(
|
980 |
+
lambda: current_prerendered_image.value,
|
981 |
+
inputs=None,
|
982 |
+
outputs=[input_image], scroll_to_output=True
|
983 |
+
)
|
984 |
+
output_overlay_composite.change(
|
985 |
+
fn=combine_images_with_lerp,
|
986 |
+
inputs=[input_image, output_image, output_overlay_composite],
|
987 |
+
outputs=[overlay_image], scroll_to_output=True
|
988 |
+
)
|
989 |
+
output_blend_multiply_composite.change(
|
990 |
+
fn=multiply_and_blend_images,
|
991 |
+
inputs=[input_image, output_image, output_blend_multiply_composite],
|
992 |
+
outputs=[overlay_image],
|
993 |
+
scroll_to_output=True
|
994 |
+
)
|
995 |
+
output_alpha_composite.change(
|
996 |
+
fn=alpha_composite_with_control,
|
997 |
+
inputs=[input_image, output_image, output_alpha_composite],
|
998 |
+
outputs=[overlay_image],
|
999 |
+
scroll_to_output=True
|
1000 |
+
)
|
1001 |
+
add_border_button.click(
|
1002 |
+
fn=lambda image_source, mask_w, mask_h, color, opacity, input_img, overlay_img: add_border(input_img if image_source == "Input Image" else overlay_img, mask_w, mask_h, update_color_opacity(detect_color_format(color), opacity * 2.55)),
|
1003 |
+
inputs=[border_image_source, mask_width, mask_height, margin_color, margin_opacity, input_image, overlay_image],
|
1004 |
+
outputs=[bordered_image_output],
|
1005 |
+
scroll_to_output=True
|
1006 |
+
)
|
1007 |
+
(())
|
1008 |
beeuty.queue(default_concurrency_limit=1,max_size=12,api_open=False)
|
1009 |
+
beeuty.launch(allowed_paths=["assets","/","./assets","images","./images", "./images/prerendered"], favicon_path="./assets/favicon.ico", max_file_size="10mb")
|
1010 |
+
|
1011 |
+
|
1012 |
+
if __name__ == "__main__":
|
1013 |
+
logging.basicConfig(
|
1014 |
+
format="[%(levelname)s] %(asctime)s %(message)s", level=logging.INFO
|
1015 |
+
)
|
1016 |
+
logging.info("Environment Variables: %s" % os.environ)
|
1017 |
+
if _get_output(["nvcc", "--version"]) is None:
|
1018 |
+
logging.info("Installing CUDA toolkit...")
|
1019 |
+
install_cuda_toolkit()
|
1020 |
+
else:
|
1021 |
+
logging.info("Detected CUDA: %s" % _get_output(["nvcc", "--version"]))
|
1022 |
+
|
1023 |
+
logging.info("Installing CUDA extensions...")
|
1024 |
+
setup_runtime_env()
|
1025 |
+
main(os.getenv("DEBUG") == "1")
|
pre-requirements.txt
CHANGED
@@ -1 +1,5 @@
|
|
1 |
-
pip>=25.0
|
|
|
|
|
|
|
|
|
|
1 |
+
pip>=25.0.1
|
2 |
+
#torch==2.4.0 --extra-index-url https://download.pytorch.org/whl/cu124
|
3 |
+
#torch-2.4.0%2Bcu124-cp310-cp310-linux_x86_64.whl#sha256=2cb28155635e3d3d0be198e3f3e7457a1d7b99e8c2eedc73fe22fab574d11a4c
|
4 |
+
#torchvision==0.19.0 --extra-index-url https://download.pytorch.org/whl/cu124
|
5 |
+
#/torchvision-0.19.0%2Bcu124-cp310-cp310-linux_x86_64.whl#sha256=82cf10450537aeb9584ceaf53633f177bb809d563c5d64526f4b9be7668b2769
|
requirements.txt
CHANGED
@@ -1,37 +1,44 @@
|
|
|
|
|
|
|
|
1 |
accelerate
|
|
|
|
|
2 |
invisible_watermark
|
|
|
3 |
# Updated versions 2.4.0+cu124
|
4 |
-
|
5 |
-
#
|
6 |
-
#
|
|
|
7 |
#xformers --index-url https://download.pytorch.org/whl/cu124
|
8 |
# ==0.0.27.post2 --index-url https://download.pytorch.org/whl/cu118/xformers-0.0.27.post2%2Bcu118-cp310-cp310-manylinux2014_x86_64.whl#sha256=b3cdeeb9eae4547805ab8c3c645ac2fa9c6da85b46c039d9befa117e9f6f22fe
|
9 |
|
10 |
#generic Torch versions
|
|
|
11 |
torch
|
12 |
-
|
|
|
13 |
|
14 |
# Other dependencies
|
15 |
Haishoku
|
16 |
pybind11>=2.12
|
17 |
huggingface_hub
|
18 |
-
# git+https://github.com/huggingface/[email protected].
|
19 |
-
|
20 |
-
gradio[oauth]
|
21 |
Pillow>=11.0.0
|
22 |
numpy
|
23 |
requests
|
24 |
-
|
25 |
-
#diffusers[torch]
|
26 |
peft
|
27 |
opencv-python
|
28 |
open3d
|
29 |
-
protobuf
|
30 |
safetensors
|
31 |
sentencepiece
|
32 |
git+https://github.com/asomoza/image_gen_aux.git
|
33 |
#git+https://github.com/huggingface/optimum.git
|
34 |
-
#git+https://github.com/triton-lang/triton.git
|
35 |
tiktoken
|
36 |
#pilmoji[requests]==2.0.4
|
37 |
#emoji==2.2.0
|
@@ -41,4 +48,5 @@ pangocffi
|
|
41 |
pangocairocffi
|
42 |
#tensorflow
|
43 |
cairosvg
|
44 |
-
python-dotenv
|
|
|
|
1 |
+
git+https://github.com/huggingface/diffusers.git
|
2 |
+
#diffusers[torch]==0.32.2
|
3 |
+
transformers
|
4 |
accelerate
|
5 |
+
safetensors
|
6 |
+
sentencepiece
|
7 |
invisible_watermark
|
8 |
+
|
9 |
# Updated versions 2.4.0+cu124
|
10 |
+
#--extra-index-url https://download.pytorch.org/whl/cu124
|
11 |
+
#torch==2.6.0 --index-url https://download.pytorch.org/whl/cu124/torch-2.4.0%2Bcu124-cp310-cp310-linux_x86_64.whl#sha256=2cb28155635e3d3d0be198e3f3e7457a1d7b99e8c2eedc73fe22fab574d11a4c
|
12 |
+
#torchvision==0.21.0 --index-url https://download.pytorch.org/whl/cu124/torchvision-0.19.0%2Bcu124-cp310-cp310-linux_x86_64.whl#sha256=82cf10450537aeb9584ceaf53633f177bb809d563c5d64526f4b9be7668b2769
|
13 |
+
#torchaudio==2.6.0 --index-url https://download.pytorch.org/whl/cu124
|
14 |
#xformers --index-url https://download.pytorch.org/whl/cu124
|
15 |
# ==0.0.27.post2 --index-url https://download.pytorch.org/whl/cu118/xformers-0.0.27.post2%2Bcu118-cp310-cp310-manylinux2014_x86_64.whl#sha256=b3cdeeb9eae4547805ab8c3c645ac2fa9c6da85b46c039d9befa117e9f6f22fe
|
16 |
|
17 |
#generic Torch versions
|
18 |
+
#--extra-index-url https://download.pytorch.org/whl/cu124
|
19 |
torch
|
20 |
+
torchvision
|
21 |
+
#xformers #==0.0.29.post3
|
22 |
|
23 |
# Other dependencies
|
24 |
Haishoku
|
25 |
pybind11>=2.12
|
26 |
huggingface_hub
|
27 |
+
# git+https://github.com/huggingface/[email protected].3#egg=transformers
|
28 |
+
#gradio[oauth]
|
|
|
29 |
Pillow>=11.0.0
|
30 |
numpy
|
31 |
requests
|
32 |
+
|
|
|
33 |
peft
|
34 |
opencv-python
|
35 |
open3d
|
36 |
+
protobuf #==3.20.3
|
37 |
safetensors
|
38 |
sentencepiece
|
39 |
git+https://github.com/asomoza/image_gen_aux.git
|
40 |
#git+https://github.com/huggingface/optimum.git
|
41 |
+
#git+https://github.com/triton-lang/triton.git #-not windows supported --disable in environment variable
|
42 |
tiktoken
|
43 |
#pilmoji[requests]==2.0.4
|
44 |
#emoji==2.2.0
|
|
|
48 |
pangocairocffi
|
49 |
#tensorflow
|
50 |
cairosvg
|
51 |
+
python-dotenv
|
52 |
+
#git+https://github.com/gradio-app/[email protected]#egg=gradio
|
src/condition.py
CHANGED
@@ -1,4 +1,6 @@
|
|
1 |
-
import
|
|
|
|
|
2 |
from typing import Optional, Union, List, Tuple
|
3 |
from diffusers.pipelines import FluxPipeline
|
4 |
from PIL import Image, ImageFilter
|
@@ -13,13 +15,13 @@ condition_dict = {
|
|
13 |
"deblurring": 7,
|
14 |
"fill": 9,
|
15 |
}
|
16 |
-
|
17 |
class Condition(object):
|
18 |
def __init__(
|
19 |
self,
|
20 |
condition_type: str,
|
21 |
-
raw_img: Union[Image.Image,
|
22 |
-
condition: Union[Image.Image,
|
23 |
mask=None,
|
24 |
) -> None:
|
25 |
self.condition_type = condition_type
|
@@ -31,8 +33,8 @@ class Condition(object):
|
|
31 |
# TODO: Add mask support
|
32 |
assert mask is None, "Mask not supported yet"
|
33 |
def get_condition(
|
34 |
-
self, condition_type: str, raw_img: Union[Image.Image,
|
35 |
-
) -> Union[Image.Image,
|
36 |
"""
|
37 |
Returns the condition image.
|
38 |
"""
|
@@ -77,7 +79,7 @@ class Condition(object):
|
|
77 |
Returns the type id of the condition.
|
78 |
"""
|
79 |
return condition_dict[condition_type]
|
80 |
-
def _encode_image(self, pipe: FluxPipeline, cond_img: Image.Image) ->
|
81 |
"""
|
82 |
Encodes an image condition into tokens using the pipeline.
|
83 |
"""
|
@@ -96,7 +98,7 @@ class Condition(object):
|
|
96 |
pipe.dtype,
|
97 |
)
|
98 |
return cond_tokens, cond_ids
|
99 |
-
def encode(self, pipe: FluxPipeline) -> Tuple[
|
100 |
"""
|
101 |
Encodes the condition into tokens, ids and type_id.
|
102 |
"""
|
@@ -113,5 +115,5 @@ class Condition(object):
|
|
113 |
raise NotImplementedError(
|
114 |
f"Condition type {self.condition_type} not implemented"
|
115 |
)
|
116 |
-
type_id =
|
117 |
return tokens, ids, type_id
|
|
|
1 |
+
import spaces
|
2 |
+
import gradio as gr
|
3 |
+
from torch import Tensor, ones_like
|
4 |
from typing import Optional, Union, List, Tuple
|
5 |
from diffusers.pipelines import FluxPipeline
|
6 |
from PIL import Image, ImageFilter
|
|
|
15 |
"deblurring": 7,
|
16 |
"fill": 9,
|
17 |
}
|
18 |
+
@spaces.GPU(progress=gr.Progress(track_tqdm=True))
|
19 |
class Condition(object):
|
20 |
def __init__(
|
21 |
self,
|
22 |
condition_type: str,
|
23 |
+
raw_img: Union[Image.Image, Tensor] = None,
|
24 |
+
condition: Union[Image.Image,Tensor] = None,
|
25 |
mask=None,
|
26 |
) -> None:
|
27 |
self.condition_type = condition_type
|
|
|
33 |
# TODO: Add mask support
|
34 |
assert mask is None, "Mask not supported yet"
|
35 |
def get_condition(
|
36 |
+
self, condition_type: str, raw_img: Union[Image.Image, Tensor]
|
37 |
+
) -> Union[Image.Image, Tensor]:
|
38 |
"""
|
39 |
Returns the condition image.
|
40 |
"""
|
|
|
79 |
Returns the type id of the condition.
|
80 |
"""
|
81 |
return condition_dict[condition_type]
|
82 |
+
def _encode_image(self, pipe: FluxPipeline, cond_img: Image.Image) -> Tensor:
|
83 |
"""
|
84 |
Encodes an image condition into tokens using the pipeline.
|
85 |
"""
|
|
|
98 |
pipe.dtype,
|
99 |
)
|
100 |
return cond_tokens, cond_ids
|
101 |
+
def encode(self, pipe: FluxPipeline) -> Tuple[Tensor, Tensor, int]:
|
102 |
"""
|
103 |
Encodes the condition into tokens, ids and type_id.
|
104 |
"""
|
|
|
115 |
raise NotImplementedError(
|
116 |
f"Condition type {self.condition_type} not implemented"
|
117 |
)
|
118 |
+
type_id = ones_like(ids[:, :1]) * self.type_id
|
119 |
return tokens, ids, type_id
|
utils/ai_generator.py
CHANGED
@@ -2,11 +2,11 @@
|
|
2 |
import gradio as gr
|
3 |
import os
|
4 |
import time
|
5 |
-
from turtle import width # Added for implementing delays
|
6 |
-
import
|
7 |
import random
|
8 |
from utils.ai_generator_diffusers_flux import generate_ai_image_local
|
9 |
-
from pathlib import Path
|
10 |
from huggingface_hub import InferenceClient
|
11 |
import requests
|
12 |
import io
|
@@ -38,12 +38,14 @@ def generate_ai_image(
|
|
38 |
width=912,
|
39 |
height=512,
|
40 |
strength=0.5,
|
41 |
-
seed =
|
42 |
progress=gr.Progress(track_tqdm=True),
|
43 |
*args,
|
44 |
**kwargs
|
45 |
-
):
|
46 |
-
if
|
|
|
|
|
47 |
print("Local GPU available. Generating image locally.")
|
48 |
if conditioned_image is not None:
|
49 |
pipeline = "FluxImg2ImgPipeline"
|
|
|
2 |
import gradio as gr
|
3 |
import os
|
4 |
import time
|
5 |
+
#from turtle import width # Added for implementing delays
|
6 |
+
from torch import cuda
|
7 |
import random
|
8 |
from utils.ai_generator_diffusers_flux import generate_ai_image_local
|
9 |
+
#from pathlib import Path
|
10 |
from huggingface_hub import InferenceClient
|
11 |
import requests
|
12 |
import io
|
|
|
38 |
width=912,
|
39 |
height=512,
|
40 |
strength=0.5,
|
41 |
+
seed = 0,
|
42 |
progress=gr.Progress(track_tqdm=True),
|
43 |
*args,
|
44 |
**kwargs
|
45 |
+
):
|
46 |
+
if seed == 0:
|
47 |
+
seed = random.randint(0, constants.MAX_SEED)
|
48 |
+
if (cuda.is_available() and cuda.device_count() >= 1): # Check if a local GPU is available
|
49 |
print("Local GPU available. Generating image locally.")
|
50 |
if conditioned_image is not None:
|
51 |
pipeline = "FluxImg2ImgPipeline"
|
utils/ai_generator_diffusers_flux.py
CHANGED
@@ -1,19 +1,19 @@
|
|
1 |
# utils/ai_generator_diffusers_flux.py
|
2 |
-
import spaces
|
3 |
-
import gradio as gr
|
4 |
import os
|
5 |
import utils.constants as constants
|
6 |
-
import
|
|
|
|
|
7 |
from diffusers import FluxPipeline,FluxImg2ImgPipeline,FluxControlPipeline
|
8 |
-
import accelerate
|
9 |
from transformers import AutoTokenizer
|
10 |
import safetensors
|
11 |
-
import xformers
|
12 |
-
from diffusers.utils import load_image
|
13 |
-
from huggingface_hub import hf_hub_download
|
14 |
from PIL import Image
|
15 |
from tempfile import NamedTemporaryFile
|
16 |
-
|
17 |
from utils.image_utils import (
|
18 |
crop_and_resize_image,
|
19 |
)
|
@@ -21,23 +21,26 @@ from utils.version_info import (
|
|
21 |
get_torch_info,
|
22 |
get_diffusers_version,
|
23 |
get_transformers_version,
|
24 |
-
get_xformers_version
|
|
|
|
|
25 |
)
|
|
|
26 |
from utils.lora_details import get_trigger_words, approximate_token_count, split_prompt_precisely
|
27 |
-
from utils.color_utils import detect_color_format
|
28 |
-
import utils.misc as misc
|
29 |
-
from pathlib import Path
|
30 |
import warnings
|
31 |
warnings.filterwarnings("ignore", message=".*Torch was not compiled with flash attention.*")
|
32 |
-
#print(
|
33 |
-
#print(
|
34 |
|
35 |
PIPELINE_CLASSES = {
|
36 |
"FluxPipeline": FluxPipeline,
|
37 |
"FluxImg2ImgPipeline": FluxImg2ImgPipeline,
|
38 |
"FluxControlPipeline": FluxControlPipeline
|
39 |
}
|
40 |
-
|
41 |
def generate_image_from_text(
|
42 |
text,
|
43 |
model_name="black-forest-labs/FLUX.1-dev",
|
@@ -51,13 +54,14 @@ def generate_image_from_text(
|
|
51 |
additional_parameters=None,
|
52 |
progress=gr.Progress(track_tqdm=True)
|
53 |
):
|
54 |
-
|
|
|
55 |
print(f"device:{device}\nmodel_name:{model_name}\n")
|
56 |
|
57 |
# Initialize the pipeline
|
58 |
pipe = FluxPipeline.from_pretrained(
|
59 |
model_name,
|
60 |
-
torch_dtype=
|
61 |
).to(device)
|
62 |
pipe.enable_model_cpu_offload()
|
63 |
|
@@ -88,7 +92,7 @@ def generate_image_from_text(
|
|
88 |
pipe.load_lora_weights(lora_weight, use_auth_token=constants.HF_API_TOKEN)
|
89 |
|
90 |
# Set the random seed for reproducibility
|
91 |
-
generator =
|
92 |
conditions = []
|
93 |
|
94 |
# Handle conditioned image if provided
|
@@ -122,12 +126,12 @@ def generate_image_from_text(
|
|
122 |
del conditions
|
123 |
del generator
|
124 |
del pipe
|
125 |
-
|
126 |
-
|
127 |
|
128 |
return image
|
129 |
|
130 |
-
|
131 |
def generate_image_lowmem(
|
132 |
text,
|
133 |
neg_prompt=None,
|
@@ -141,50 +145,59 @@ def generate_image_lowmem(
|
|
141 |
seed=0,
|
142 |
true_cfg_scale=1.0,
|
143 |
pipeline_name="FluxPipeline",
|
144 |
-
strength=0.75,
|
145 |
additional_parameters=None,
|
146 |
progress=gr.Progress(track_tqdm=True)
|
147 |
-
):
|
148 |
# Retrieve the pipeline class from the mapping
|
149 |
pipeline_class = PIPELINE_CLASSES.get(pipeline_name)
|
150 |
if not pipeline_class:
|
151 |
raise ValueError(f"Unsupported pipeline type '{pipeline_name}'. "
|
152 |
f"Available options: {list(PIPELINE_CLASSES.keys())}")
|
153 |
|
154 |
-
|
|
|
|
|
|
|
155 |
print(f"device:{device}\nmodel_name:{model_name}\nlora_weights:{lora_weights}\n")
|
156 |
print(f"\n {get_torch_info()}\n")
|
157 |
# Disable gradient calculations
|
158 |
-
with
|
159 |
# Initialize the pipeline inside the context manager
|
160 |
pipe = pipeline_class.from_pretrained(
|
161 |
model_name,
|
162 |
-
torch_dtype=
|
163 |
).to(device)
|
164 |
# Optionally, don't use CPU offload if not necessary
|
165 |
-
|
166 |
# alternative version that may be more efficient
|
167 |
# pipe.enable_sequential_cpu_offload()
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
|
169 |
# Access the tokenizer from the pipeline
|
170 |
tokenizer = pipe.tokenizer
|
171 |
|
172 |
# Check if add_prefix_space is set and convert to slow tokenizer if necessary
|
173 |
if getattr(tokenizer, 'add_prefix_space', False):
|
174 |
-
tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=False)
|
175 |
# Update the pipeline's tokenizer
|
176 |
pipe.tokenizer = tokenizer
|
|
|
177 |
|
178 |
-
flash_attention_enabled =
|
179 |
if flash_attention_enabled == False:
|
180 |
#Enable xFormers memory-efficient attention (optional)
|
181 |
-
pipe.enable_xformers_memory_efficient_attention()
|
182 |
print("\nEnabled xFormers memory-efficient attention.\n")
|
183 |
else:
|
184 |
pipe.attn_implementation="flash_attention_2"
|
185 |
print("\nEnabled flash_attention_2.\n")
|
186 |
-
|
187 |
-
pipe.enable_vae_tiling()
|
188 |
condition_type = "subject"
|
189 |
# Load LoRA weights
|
190 |
# note: does not yet handle multiple LoRA weights with different names, needs .set_adapters(["depth", "hyper-sd"], adapter_weights=[0.85, 0.125])
|
@@ -275,7 +288,7 @@ def generate_image_lowmem(
|
|
275 |
else:
|
276 |
pipe.load_lora_weights(lora_weight, use_auth_token=constants.HF_API_TOKEN)
|
277 |
# Set the random seed for reproducibility
|
278 |
-
generator =
|
279 |
conditions = []
|
280 |
if conditioned_image is not None:
|
281 |
conditioned_image = crop_and_resize_image(conditioned_image, image_width, image_height)
|
@@ -327,9 +340,10 @@ def generate_image_lowmem(
|
|
327 |
del generator
|
328 |
# Delete the pipeline and clear cache
|
329 |
del pipe
|
330 |
-
|
331 |
-
|
332 |
-
print(
|
|
|
333 |
return image
|
334 |
|
335 |
def generate_ai_image_local (
|
@@ -348,6 +362,8 @@ def generate_ai_image_local (
|
|
348 |
strength=0.75,
|
349 |
progress=gr.Progress(track_tqdm=True)
|
350 |
):
|
|
|
|
|
351 |
try:
|
352 |
if map_option != "Prompt":
|
353 |
prompt = constants.PROMPTS[map_option]
|
@@ -387,6 +403,7 @@ def generate_ai_image_local (
|
|
387 |
print(f"Seed: {seed}")
|
388 |
print(f"Additional Parameters: {additional_parameters}")
|
389 |
print(f"Conditioned Image: {conditioned_image}")
|
|
|
390 |
print(f"pipeline: {pipeline_name}")
|
391 |
image = generate_image_lowmem(
|
392 |
text=prompt,
|
@@ -400,15 +417,18 @@ def generate_ai_image_local (
|
|
400 |
num_inference_steps=num_inference_steps,
|
401 |
seed=seed,
|
402 |
pipeline_name=pipeline_name,
|
|
|
403 |
additional_parameters=additional_parameters
|
404 |
)
|
405 |
with NamedTemporaryFile(delete=False, suffix=".png") as tmp:
|
406 |
image.save(tmp.name, format="PNG")
|
407 |
constants.temp_files.append(tmp.name)
|
408 |
print(f"Image saved to {tmp.name}")
|
|
|
409 |
return tmp.name
|
410 |
except Exception as e:
|
411 |
print(f"Error generating AI image: {e}")
|
|
|
412 |
return None
|
413 |
|
414 |
# does not work
|
@@ -419,7 +439,7 @@ def merge_LoRA_weights(model="black-forest-labs/FLUX.1-dev",
|
|
419 |
if model_suffix not in lora_weights:
|
420 |
raise ValueError(f"The model suffix '{model_suffix}' must be in the lora_weights string '{lora_weights}' to proceed.")
|
421 |
|
422 |
-
pipe = FluxPipeline.from_pretrained(model, torch_dtype=
|
423 |
pipe.load_lora_weights(lora_weights)
|
424 |
pipe.save_lora_weights(os.getenv("TMPDIR"))
|
425 |
lora_name = lora_weights.split("/")[-1] + "-merged"
|
|
|
1 |
# utils/ai_generator_diffusers_flux.py
|
|
|
|
|
2 |
import os
|
3 |
import utils.constants as constants
|
4 |
+
#import spaces
|
5 |
+
import gradio as gr
|
6 |
+
from torch import __version__ as torch_version_, version, cuda, bfloat16, float32, Generator, no_grad, backends
|
7 |
from diffusers import FluxPipeline,FluxImg2ImgPipeline,FluxControlPipeline
|
8 |
+
#import accelerate
|
9 |
from transformers import AutoTokenizer
|
10 |
import safetensors
|
11 |
+
#import xformers
|
12 |
+
#from diffusers.utils import load_image
|
13 |
+
#from huggingface_hub import hf_hub_download
|
14 |
from PIL import Image
|
15 |
from tempfile import NamedTemporaryFile
|
16 |
+
|
17 |
from utils.image_utils import (
|
18 |
crop_and_resize_image,
|
19 |
)
|
|
|
21 |
get_torch_info,
|
22 |
get_diffusers_version,
|
23 |
get_transformers_version,
|
24 |
+
get_xformers_version,
|
25 |
+
initialize_cuda,
|
26 |
+
release_torch_resources
|
27 |
)
|
28 |
+
import gc
|
29 |
from utils.lora_details import get_trigger_words, approximate_token_count, split_prompt_precisely
|
30 |
+
#from utils.color_utils import detect_color_format
|
31 |
+
#import utils.misc as misc
|
32 |
+
#from pathlib import Path
|
33 |
import warnings
|
34 |
warnings.filterwarnings("ignore", message=".*Torch was not compiled with flash attention.*")
|
35 |
+
#print(torch_version_) # Ensure it's 2.0 or newer
|
36 |
+
#print(cuda.is_available()) # Ensure CUDA is available
|
37 |
|
38 |
PIPELINE_CLASSES = {
|
39 |
"FluxPipeline": FluxPipeline,
|
40 |
"FluxImg2ImgPipeline": FluxImg2ImgPipeline,
|
41 |
"FluxControlPipeline": FluxControlPipeline
|
42 |
}
|
43 |
+
#@spaces.GPU()
|
44 |
def generate_image_from_text(
|
45 |
text,
|
46 |
model_name="black-forest-labs/FLUX.1-dev",
|
|
|
54 |
additional_parameters=None,
|
55 |
progress=gr.Progress(track_tqdm=True)
|
56 |
):
|
57 |
+
from src.condition import Condition
|
58 |
+
device = "cuda" if cuda.is_available() else "cpu"
|
59 |
print(f"device:{device}\nmodel_name:{model_name}\n")
|
60 |
|
61 |
# Initialize the pipeline
|
62 |
pipe = FluxPipeline.from_pretrained(
|
63 |
model_name,
|
64 |
+
torch_dtype=bfloat16 if device == "cuda" else float32
|
65 |
).to(device)
|
66 |
pipe.enable_model_cpu_offload()
|
67 |
|
|
|
92 |
pipe.load_lora_weights(lora_weight, use_auth_token=constants.HF_API_TOKEN)
|
93 |
|
94 |
# Set the random seed for reproducibility
|
95 |
+
generator = Generator(device=device).manual_seed(seed)
|
96 |
conditions = []
|
97 |
|
98 |
# Handle conditioned image if provided
|
|
|
126 |
del conditions
|
127 |
del generator
|
128 |
del pipe
|
129 |
+
cuda.empty_cache()
|
130 |
+
cuda.ipc_collect()
|
131 |
|
132 |
return image
|
133 |
|
134 |
+
#@spaces.GPU(progress=gr.Progress(track_tqdm=True))
|
135 |
def generate_image_lowmem(
|
136 |
text,
|
137 |
neg_prompt=None,
|
|
|
145 |
seed=0,
|
146 |
true_cfg_scale=1.0,
|
147 |
pipeline_name="FluxPipeline",
|
148 |
+
strength=0.75,
|
149 |
additional_parameters=None,
|
150 |
progress=gr.Progress(track_tqdm=True)
|
151 |
+
):
|
152 |
# Retrieve the pipeline class from the mapping
|
153 |
pipeline_class = PIPELINE_CLASSES.get(pipeline_name)
|
154 |
if not pipeline_class:
|
155 |
raise ValueError(f"Unsupported pipeline type '{pipeline_name}'. "
|
156 |
f"Available options: {list(PIPELINE_CLASSES.keys())}")
|
157 |
|
158 |
+
initialize_cuda()
|
159 |
+
device = "cuda" if cuda.is_available() else "cpu"
|
160 |
+
from src.condition import Condition
|
161 |
+
|
162 |
print(f"device:{device}\nmodel_name:{model_name}\nlora_weights:{lora_weights}\n")
|
163 |
print(f"\n {get_torch_info()}\n")
|
164 |
# Disable gradient calculations
|
165 |
+
with no_grad():
|
166 |
# Initialize the pipeline inside the context manager
|
167 |
pipe = pipeline_class.from_pretrained(
|
168 |
model_name,
|
169 |
+
torch_dtype=bfloat16 if device == "cuda" else float32
|
170 |
).to(device)
|
171 |
# Optionally, don't use CPU offload if not necessary
|
172 |
+
|
173 |
# alternative version that may be more efficient
|
174 |
# pipe.enable_sequential_cpu_offload()
|
175 |
+
if pipeline_name == "FluxPipeline":
|
176 |
+
pipe.enable_model_cpu_offload()
|
177 |
+
pipe.vae.enable_slicing()
|
178 |
+
pipe.vae.enable_tiling()
|
179 |
+
else:
|
180 |
+
pipe.enable_model_cpu_offload()
|
181 |
|
182 |
# Access the tokenizer from the pipeline
|
183 |
tokenizer = pipe.tokenizer
|
184 |
|
185 |
# Check if add_prefix_space is set and convert to slow tokenizer if necessary
|
186 |
if getattr(tokenizer, 'add_prefix_space', False):
|
187 |
+
tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=False, device_map = 'cpu')
|
188 |
# Update the pipeline's tokenizer
|
189 |
pipe.tokenizer = tokenizer
|
190 |
+
pipe.to(device)
|
191 |
|
192 |
+
flash_attention_enabled = backends.cuda.flash_sdp_enabled()
|
193 |
if flash_attention_enabled == False:
|
194 |
#Enable xFormers memory-efficient attention (optional)
|
195 |
+
#pipe.enable_xformers_memory_efficient_attention()
|
196 |
print("\nEnabled xFormers memory-efficient attention.\n")
|
197 |
else:
|
198 |
pipe.attn_implementation="flash_attention_2"
|
199 |
print("\nEnabled flash_attention_2.\n")
|
200 |
+
|
|
|
201 |
condition_type = "subject"
|
202 |
# Load LoRA weights
|
203 |
# note: does not yet handle multiple LoRA weights with different names, needs .set_adapters(["depth", "hyper-sd"], adapter_weights=[0.85, 0.125])
|
|
|
288 |
else:
|
289 |
pipe.load_lora_weights(lora_weight, use_auth_token=constants.HF_API_TOKEN)
|
290 |
# Set the random seed for reproducibility
|
291 |
+
generator = Generator(device=device).manual_seed(seed)
|
292 |
conditions = []
|
293 |
if conditioned_image is not None:
|
294 |
conditioned_image = crop_and_resize_image(conditioned_image, image_width, image_height)
|
|
|
340 |
del generator
|
341 |
# Delete the pipeline and clear cache
|
342 |
del pipe
|
343 |
+
cuda.empty_cache()
|
344 |
+
cuda.ipc_collect()
|
345 |
+
print(cuda.memory_summary(device=None, abbreviated=False))
|
346 |
+
|
347 |
return image
|
348 |
|
349 |
def generate_ai_image_local (
|
|
|
362 |
strength=0.75,
|
363 |
progress=gr.Progress(track_tqdm=True)
|
364 |
):
|
365 |
+
release_torch_resources()
|
366 |
+
print(f"Generating image with lowmem")
|
367 |
try:
|
368 |
if map_option != "Prompt":
|
369 |
prompt = constants.PROMPTS[map_option]
|
|
|
403 |
print(f"Seed: {seed}")
|
404 |
print(f"Additional Parameters: {additional_parameters}")
|
405 |
print(f"Conditioned Image: {conditioned_image}")
|
406 |
+
print(f"Conditioned Image Strength: {strength}")
|
407 |
print(f"pipeline: {pipeline_name}")
|
408 |
image = generate_image_lowmem(
|
409 |
text=prompt,
|
|
|
417 |
num_inference_steps=num_inference_steps,
|
418 |
seed=seed,
|
419 |
pipeline_name=pipeline_name,
|
420 |
+
strength=strength,
|
421 |
additional_parameters=additional_parameters
|
422 |
)
|
423 |
with NamedTemporaryFile(delete=False, suffix=".png") as tmp:
|
424 |
image.save(tmp.name, format="PNG")
|
425 |
constants.temp_files.append(tmp.name)
|
426 |
print(f"Image saved to {tmp.name}")
|
427 |
+
gc.collect()
|
428 |
return tmp.name
|
429 |
except Exception as e:
|
430 |
print(f"Error generating AI image: {e}")
|
431 |
+
gc.collect()
|
432 |
return None
|
433 |
|
434 |
# does not work
|
|
|
439 |
if model_suffix not in lora_weights:
|
440 |
raise ValueError(f"The model suffix '{model_suffix}' must be in the lora_weights string '{lora_weights}' to proceed.")
|
441 |
|
442 |
+
pipe = FluxPipeline.from_pretrained(model, torch_dtype=bfloat16)
|
443 |
pipe.load_lora_weights(lora_weights)
|
444 |
pipe.save_lora_weights(os.getenv("TMPDIR"))
|
445 |
lora_name = lora_weights.split("/")[-1] + "-merged"
|
utils/constants.py
CHANGED
@@ -10,12 +10,18 @@ import numpy as np
|
|
10 |
os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "max_split_size_mb:256,expandable_segments:True"
|
11 |
os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'
|
12 |
#os.environ["TF_CPP_MIN_LOG_LEVEL"] = '2'
|
|
|
13 |
os.environ['USE_FLASH_ATTENTION'] = '1'
|
14 |
-
|
15 |
#os.environ['XFORMERS_FORCE_DISABLE_TORCHSCRIPT']= '1'
|
16 |
-
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
|
17 |
os.environ["PYTORCH_NVML_BASED_CUDA_CHECK"] = "1"
|
18 |
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
|
|
|
|
|
|
|
|
|
|
|
19 |
|
20 |
IS_SHARED_SPACE = "Surn/HexaGrid" in os.environ.get('SPACE_ID', '')
|
21 |
|
@@ -36,14 +42,14 @@ default_lut_example_img = "./LUT/daisy.jpg"
|
|
36 |
MAX_SEED = np.iinfo(np.int32).max
|
37 |
|
38 |
PROMPTS = {
|
39 |
-
"BorderBlack": "
|
40 |
-
"Earth": "
|
41 |
-
"Map3": "
|
42 |
-
"Map4": "
|
43 |
-
"Alien Landscape": "
|
44 |
-
"Alien World": "
|
45 |
-
"Mystic Forest": "
|
46 |
-
"Medieval Battlefield": "
|
47 |
"Prompt": None # Indicates that the prompt should be taken from prompt_textbox
|
48 |
}
|
49 |
|
@@ -152,7 +158,8 @@ LORA_WEIGHTS = [
|
|
152 |
"Cossale/Frames2-Flex.1",
|
153 |
"XLabs-AI/flux-lora-collection/anime_lora.safetensors",
|
154 |
"XLabs-AI/flux-lora-collection/scenery_lora.safetensors",
|
155 |
-
"XLabs-AI/flux-lora-collection/disney_lora.safetensors"
|
|
|
156 |
]
|
157 |
|
158 |
# Map each LoRA weight to its corresponding model
|
@@ -164,7 +171,8 @@ LORA_TO_MODEL = {
|
|
164 |
"AlekseyCalvin/HSTcolorFlexAlpha": "ostris/Flex.1-alpha",
|
165 |
"XLabs-AI/flux-lora-collection/anime_lora.safetensors":"black-forest-labs/FLUX.1-dev",
|
166 |
"XLabs-AI/flux-lora-collection/scenery_lora.safetensors":"black-forest-labs/FLUX.1-dev",
|
167 |
-
"XLabs-AI/flux-lora-collection/disney_lora.safetensors":"black-forest-labs/FLUX.1-dev"
|
|
|
168 |
}
|
169 |
condition_type = ["depth", "canny", "subject", "coloring", "deblurring", "fill", "redux"]
|
170 |
# Detailed LoRA weight configurations
|
@@ -236,6 +244,18 @@ LORA_DETAILS = {
|
|
236 |
}
|
237 |
}
|
238 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
239 |
"Cossale/Frames2-Flex.1": [
|
240 |
{
|
241 |
"weight_name": "backdrops_v2.safetensors",
|
|
|
10 |
os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "max_split_size_mb:256,expandable_segments:True"
|
11 |
os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'
|
12 |
#os.environ["TF_CPP_MIN_LOG_LEVEL"] = '2'
|
13 |
+
os.environ['CUDA_MODULE_LOADING']='LAZY'
|
14 |
os.environ['USE_FLASH_ATTENTION'] = '1'
|
15 |
+
os.environ['XFORMERS_FORCE_DISABLE_TRITON']= '1'
|
16 |
#os.environ['XFORMERS_FORCE_DISABLE_TORCHSCRIPT']= '1'
|
17 |
+
#os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
|
18 |
os.environ["PYTORCH_NVML_BASED_CUDA_CHECK"] = "1"
|
19 |
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
|
20 |
+
os.environ["NVIDIA_VISIBLE_DEVICES"] = "0"
|
21 |
+
os.environ["ZEROGPU_VERSION"] = "2"
|
22 |
+
os.environ["ZEROGPU_V2"] = "true"
|
23 |
+
os.environ["ZERO_GPU_V2"] = "true"
|
24 |
+
os.environ["ZERO_GPU_PATCH_TORCH_DEVICE"]='1'
|
25 |
|
26 |
IS_SHARED_SPACE = "Surn/HexaGrid" in os.environ.get('SPACE_ID', '')
|
27 |
|
|
|
42 |
MAX_SEED = np.iinfo(np.int32).max
|
43 |
|
44 |
PROMPTS = {
|
45 |
+
"BorderBlack": "Top-down view of a hexagon-based alien map with black borders. Features rivers, mountains, volcanoes, and snow at top and bottom. Colors: light blue, green, tan, brown. No reflections or shadows. Partial hexes on edges are black.",
|
46 |
+
"Earth": "Top-down view of a hexagonal world map with rivers, mountains, volcanoes, and snow at top and bottom. Colors: light blue, green, tan, brown. No reflections or shadows. Partial edge hexes are black. Overhead view.",
|
47 |
+
"Map3": "Top-down view of a mystic forest map with lakes, dense forests, magical flora, and hex grids. Designed for tabletop gaming with clarity and strategic elements. Colors: light blue, green, purple, brown. Partial hexes on edges are black.",
|
48 |
+
"Map4": "Top-down view of a medieval battlefield map with lakes, forests, magical fauna, and hex grids. Emphasizes clarity and strategy for tabletop games. Colors: teal, dark green, violet, brown. Partial edge hexes are black. Viewed from above.",
|
49 |
+
"Alien Landscape": "Top-down view of a barren alien world map made from hexagon pieces. Features light blue rivers, brown mountains, red volcanoes, and white snow at top and bottom. Colors: light blue, green, tan, brown. Partial hexes on edges are black.",
|
50 |
+
"Alien World": "Top-down view of an alien world map built from hexagon pieces. Includes rivers, mountains, volcanoes, and snowy areas. Colors: light blue, green, tan, brown. Partial edge hexes are black. Overhead view.",
|
51 |
+
"Mystic Forest": "Top-down view of a mystic forest map with lakes, dense forests, magical flora, and hex grids. Designed for clarity in tabletop gaming. Colors: light blue, green, purple, brown. Partial hexes on edges are black.",
|
52 |
+
"Medieval Battlefield": "Top-down view of a medieval battlefield map featuring lakes, forests, and magic fauna. Emphasizes clarity and strategy for tabletop games. Colors: teal, dark green, violet, brown. Partial edge hexes are black. Viewed from above.",
|
53 |
"Prompt": None # Indicates that the prompt should be taken from prompt_textbox
|
54 |
}
|
55 |
|
|
|
158 |
"Cossale/Frames2-Flex.1",
|
159 |
"XLabs-AI/flux-lora-collection/anime_lora.safetensors",
|
160 |
"XLabs-AI/flux-lora-collection/scenery_lora.safetensors",
|
161 |
+
"XLabs-AI/flux-lora-collection/disney_lora.safetensors",
|
162 |
+
"XLabs-AI/flux-RealismLora"
|
163 |
]
|
164 |
|
165 |
# Map each LoRA weight to its corresponding model
|
|
|
171 |
"AlekseyCalvin/HSTcolorFlexAlpha": "ostris/Flex.1-alpha",
|
172 |
"XLabs-AI/flux-lora-collection/anime_lora.safetensors":"black-forest-labs/FLUX.1-dev",
|
173 |
"XLabs-AI/flux-lora-collection/scenery_lora.safetensors":"black-forest-labs/FLUX.1-dev",
|
174 |
+
"XLabs-AI/flux-lora-collection/disney_lora.safetensors":"black-forest-labs/FLUX.1-dev",
|
175 |
+
"XLabs-AI/flux-RealismLora":"black-forest-labs/FLUX.1-dev"
|
176 |
}
|
177 |
condition_type = ["depth", "canny", "subject", "coloring", "deblurring", "fill", "redux"]
|
178 |
# Detailed LoRA weight configurations
|
|
|
244 |
}
|
245 |
}
|
246 |
],
|
247 |
+
"XLabs-AI/flux-RealismLora":[
|
248 |
+
{
|
249 |
+
"notes": "No trigger words but 8k, Animatrix illustration style, fantasy style, natural photo cinematic should all work @6min"
|
250 |
+
},
|
251 |
+
{
|
252 |
+
"parameters" :{
|
253 |
+
"guidance_scale": "3.2",
|
254 |
+
"num_inference_steps": "34",
|
255 |
+
"scale": "0.85"
|
256 |
+
}
|
257 |
+
}
|
258 |
+
],
|
259 |
"Cossale/Frames2-Flex.1": [
|
260 |
{
|
261 |
"weight_name": "backdrops_v2.safetensors",
|
utils/misc.py
CHANGED
@@ -1,6 +1,9 @@
|
|
1 |
# misc.py file contains miscellaneous utility functions
|
2 |
import math
|
3 |
import sys
|
|
|
|
|
|
|
4 |
|
5 |
def pause():
|
6 |
"""
|
@@ -67,3 +70,78 @@ def convert_ratio_to_dimensions(ratio, height=512, rotate90=False):
|
|
67 |
adjusted_width, adjusted_height = adjusted_height, adjusted_width
|
68 |
return adjusted_width, adjusted_height
|
69 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
# misc.py file contains miscellaneous utility functions
|
2 |
import math
|
3 |
import sys
|
4 |
+
import logging
|
5 |
+
import os
|
6 |
+
import subprocess
|
7 |
|
8 |
def pause():
|
9 |
"""
|
|
|
70 |
adjusted_width, adjusted_height = adjusted_height, adjusted_width
|
71 |
return adjusted_width, adjusted_height
|
72 |
|
73 |
+
def install_torch():
|
74 |
+
print("\nInstalling PyTorch with CUDA support...")
|
75 |
+
# Define the package and index URL
|
76 |
+
package = "torch==2.4.0"
|
77 |
+
index_url = "https://download.pytorch.org/whl/cu124"
|
78 |
+
# Construct the pip install command
|
79 |
+
command = [
|
80 |
+
"pip", "install", "--force-reinstall",
|
81 |
+
f"{package}", "--index-url", f"{index_url}"
|
82 |
+
]
|
83 |
+
# Run the command using subprocess
|
84 |
+
subprocess.run(command, check=True)
|
85 |
+
print("\nPyTorch installation completed.")
|
86 |
+
print("\nInstalling torchvision...")
|
87 |
+
package = "torchvision==0.19.0"
|
88 |
+
index_url = "https://download.pytorch.org/whl/cu124"
|
89 |
+
# Construct the pip install command
|
90 |
+
command = [
|
91 |
+
"pip", "install", "--force-reinstall",
|
92 |
+
f"{package}", "--index-url", f"{index_url}"
|
93 |
+
]
|
94 |
+
# Run the command using subprocess
|
95 |
+
subprocess.run(command, check=True)
|
96 |
+
print("\nPlease restart the kernel to use the newly installed PyTorch version.")
|
97 |
+
|
98 |
+
def _get_output(cmd):
|
99 |
+
try:
|
100 |
+
return subprocess.check_output(cmd).decode("utf-8")
|
101 |
+
except Exception as ex:
|
102 |
+
logging.exception(ex)
|
103 |
+
return None
|
104 |
+
|
105 |
+
def install_cuda_toolkit():
|
106 |
+
#CUDA_TOOLKIT_URL = "https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda_11.8.0_520.61.05_linux.run"
|
107 |
+
# CUDA_TOOLKIT_URL = "https://developer.download.nvidia.com/compute/cuda/12.2.0/local_installers/cuda_12.2.0_535.54.03_linux.run"
|
108 |
+
CUDA_TOOLKIT_URL = "https://developer.download.nvidia.com/compute/cuda/12.4.1/local_installers/cuda_12.4.1_550.54.15_linux.run"
|
109 |
+
CUDA_TOOLKIT_FILE = "/tmp/%s" % os.path.basename(CUDA_TOOLKIT_URL)
|
110 |
+
print("\nDownloading CUDA Toolkit from %s" % CUDA_TOOLKIT_URL)
|
111 |
+
subprocess.call(["wget", "-q", CUDA_TOOLKIT_URL, "-O", CUDA_TOOLKIT_FILE])
|
112 |
+
subprocess.call(["chmod", "+x", CUDA_TOOLKIT_FILE])
|
113 |
+
subprocess.call([CUDA_TOOLKIT_FILE, "--silent", "--toolkit"])
|
114 |
+
os.environ["CUDA_HOME"] = "/usr/local/cuda"
|
115 |
+
os.environ["PATH"] = "%s/bin:%s" % (os.environ["CUDA_HOME"], os.environ["PATH"])
|
116 |
+
os.environ["LD_LIBRARY_PATH"] = "%s/lib:%s" % (
|
117 |
+
os.environ["CUDA_HOME"],
|
118 |
+
"" if "LD_LIBRARY_PATH" not in os.environ else os.environ["LD_LIBRARY_PATH"],
|
119 |
+
)
|
120 |
+
# Fix: arch_list[-1] += '+PTX'; IndexError: list index out of range
|
121 |
+
os.environ["TORCH_CUDA_ARCH_LIST"] = "8.0;8.6"
|
122 |
+
print("\nPlease restart the kernel to use the newly installed CUDA Toolkit.")
|
123 |
+
|
124 |
+
def setup_runtime_env():
|
125 |
+
from torch import cuda
|
126 |
+
logging.info("Python Version: %s" % _get_output(["python", "--version"]))
|
127 |
+
logging.info("CUDA Version: %s" % _get_output(["nvcc", "--version"]))
|
128 |
+
logging.info("GCC Version: %s" % _get_output(["gcc", "--version"]))
|
129 |
+
logging.info("CUDA is available: %s" % cuda.is_available())
|
130 |
+
logging.info("CUDA Device Capability: %s" % (cuda.get_device_capability(),))
|
131 |
+
|
132 |
+
# Install Pre-compiled CUDA extensions (Fallback to this solution on 12/31/24)
|
133 |
+
# Ref: https://huggingface.co/spaces/zero-gpu-explorers/README/discussions/110
|
134 |
+
##ext_dir = os.path.join(os.path.dirname(__file__), "wheels")
|
135 |
+
##for e in os.listdir(ext_dir):
|
136 |
+
## logging.info("Installing Extensions from %s" % e)
|
137 |
+
## subprocess.call(
|
138 |
+
## ["pip", "install", os.path.join(ext_dir, e)], stderr=subprocess.STDOUT
|
139 |
+
## )
|
140 |
+
# Compile CUDA extensions
|
141 |
+
# Update on 12/31/24: No module named 'torch'. But it is installed and listed by `pip list`
|
142 |
+
# ext_dir = os.path.join(os.path.dirname(__file__), "citydreamer", "extensions")
|
143 |
+
# for e in os.listdir(ext_dir):
|
144 |
+
# if os.path.isdir(os.path.join(ext_dir, e)):
|
145 |
+
# subprocess.call(["pip", "install", "."], cwd=os.path.join(ext_dir, e))
|
146 |
+
|
147 |
+
#logging.info("Installed Python Packages: %s" % _get_output(["pip", "list"]))
|
utils/version_info.py
CHANGED
@@ -2,9 +2,8 @@
|
|
2 |
|
3 |
import subprocess
|
4 |
import os
|
5 |
-
import spaces
|
6 |
-
import torch
|
7 |
import sys
|
|
|
8 |
import gradio as gr
|
9 |
|
10 |
git = os.environ.get('GIT', "git")
|
@@ -46,14 +45,46 @@ def get_diffusers_version():
|
|
46 |
return diffusers.__version__
|
47 |
except Exception:
|
48 |
return "<none>"
|
49 |
-
|
50 |
def get_torch_info():
|
|
|
|
|
51 |
try:
|
52 |
-
|
|
|
|
|
53 |
except Exception:
|
|
|
54 |
return "<none>"
|
55 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
def versions_html():
|
|
|
57 |
python_version = ".".join([str(x) for x in sys.version_info[0:3]])
|
58 |
commit = commit_hash()
|
59 |
|
@@ -64,12 +95,12 @@ def versions_html():
|
|
64 |
</a>
|
65 |
'''
|
66 |
|
67 |
-
|
68 |
version: <a href="https://huggingface.co/spaces/Surn/HexaGrid/commit/{"huggingface" if commit == "<none>" else commit}" target="_blank">{"huggingface" if commit == "<none>" else commit}</a>
|
69 |
 • 
|
70 |
python: <span title="{sys.version}">{python_version}</span>
|
71 |
 • 
|
72 |
-
torch: {
|
73 |
 • 
|
74 |
diffusers: {get_diffusers_version()}
|
75 |
 • 
|
@@ -82,4 +113,6 @@ def versions_html():
|
|
82 |
{toggle_dark_link}
|
83 |
<br>
|
84 |
Full GPU Info:{get_torch_info()}
|
85 |
-
"""
|
|
|
|
|
|
2 |
|
3 |
import subprocess
|
4 |
import os
|
|
|
|
|
5 |
import sys
|
6 |
+
import gc
|
7 |
import gradio as gr
|
8 |
|
9 |
git = os.environ.get('GIT', "git")
|
|
|
45 |
return diffusers.__version__
|
46 |
except Exception:
|
47 |
return "<none>"
|
48 |
+
|
49 |
def get_torch_info():
|
50 |
+
from torch import __version__ as torch_version_, version, cuda, backends
|
51 |
+
initialize_cuda()
|
52 |
try:
|
53 |
+
info = [torch_version_, f"CUDA Version:{version.cuda}", f"Available:{cuda.is_available()}", f"flash attention enabled: {backends.cuda.flash_sdp_enabled()}", f"Capabilities: {cuda.get_device_capability(0)}", f"Device Name: {cuda.get_device_name(0)}", f"Device Count: {cuda.device_count()}",f"Devices: {os.environ['CUDA_VISIBLE_DEVICES']}", f"Zero :{os.environ['CUDA_MODULE_LOADING']}"]
|
54 |
+
del torch_version_, version, cuda, backends
|
55 |
+
return info
|
56 |
except Exception:
|
57 |
+
del torch_version_, version, cuda, backends
|
58 |
return "<none>"
|
59 |
|
60 |
+
def release_torch_resources():
|
61 |
+
from torch import cuda
|
62 |
+
# Clear the CUDA cache
|
63 |
+
cuda.empty_cache()
|
64 |
+
cuda.ipc_collect()
|
65 |
+
# Delete any objects that are using GPU memory
|
66 |
+
#for obj in gc.get_objects():
|
67 |
+
# if is_tensor(obj) or (hasattr(obj, 'data') and is_tensor(obj.data)):
|
68 |
+
# del obj
|
69 |
+
# Run garbage collection
|
70 |
+
del cuda
|
71 |
+
gc.collect()
|
72 |
+
|
73 |
+
|
74 |
+
def initialize_cuda():
|
75 |
+
from torch import cuda, version
|
76 |
+
if cuda.is_available():
|
77 |
+
device = cuda.device("cuda")
|
78 |
+
print(f"CUDA is available. Using device: {cuda.get_device_name(0)} with CUDA version: {version.cuda}")
|
79 |
+
result = "cuda"
|
80 |
+
else:
|
81 |
+
device = cuda.device("cpu")
|
82 |
+
print("CUDA is not available. Using CPU.")
|
83 |
+
result = "cpu"
|
84 |
+
return result
|
85 |
+
|
86 |
def versions_html():
|
87 |
+
from torch import __version__ as torch_version_
|
88 |
python_version = ".".join([str(x) for x in sys.version_info[0:3]])
|
89 |
commit = commit_hash()
|
90 |
|
|
|
95 |
</a>
|
96 |
'''
|
97 |
|
98 |
+
v_html = f"""
|
99 |
version: <a href="https://huggingface.co/spaces/Surn/HexaGrid/commit/{"huggingface" if commit == "<none>" else commit}" target="_blank">{"huggingface" if commit == "<none>" else commit}</a>
|
100 |
 • 
|
101 |
python: <span title="{sys.version}">{python_version}</span>
|
102 |
 • 
|
103 |
+
torch: {torch_version_}
|
104 |
 • 
|
105 |
diffusers: {get_diffusers_version()}
|
106 |
 • 
|
|
|
113 |
{toggle_dark_link}
|
114 |
<br>
|
115 |
Full GPU Info:{get_torch_info()}
|
116 |
+
"""
|
117 |
+
del torch_version_
|
118 |
+
return v_html
|