John6666 commited on
Commit
a761054
1 Parent(s): 57302a8

Upload 4 files

Browse files
Files changed (4) hide show
  1. app.py +201 -239
  2. env.py +18 -2
  3. mod.py +32 -7
  4. requirements.txt +4 -1
app.py CHANGED
@@ -2,10 +2,12 @@ import spaces
2
  import gradio as gr
3
  import json
4
  import torch
5
- from diffusers import DiffusionPipeline, AutoencoderTiny, AutoencoderKL, AutoPipelineForImage2Image, AutoPipelineForInpainting
6
  from live_preview_helpers import calculate_shift, retrieve_timesteps, flux_pipe_call_that_returns_an_iterable_of_images
7
  from diffusers.utils import load_image
8
- from diffusers import FluxControlNetPipeline, FluxControlNetModel, FluxMultiControlNetModel, FluxControlNetImg2ImgPipeline, FluxTransformer2DModel, FluxControlNetInpaintPipeline, FluxInpaintPipeline
 
 
9
  from huggingface_hub import hf_hub_download, HfFileSystem, ModelCard, snapshot_download, HfApi
10
  import os
11
  import copy
@@ -16,10 +18,10 @@ import pandas as pd
16
  import numpy as np
17
  from pathlib import Path
18
 
19
- from env import models, num_loras, num_cns, HF_TOKEN, single_file_base_models
20
  from mod import (clear_cache, get_repo_safetensors, is_repo_name, is_repo_exists, get_model_trigger,
21
- description_ui, compose_lora_json, is_valid_lora, fuse_loras, save_image, preprocess_i2i_image,
22
- get_trigger_word, enhance_prompt, set_control_union_image,
23
  get_control_union_mode, set_control_union_mode, get_control_params, translate_to_en)
24
  from modutils import (search_civitai_lora, select_civitai_lora, search_civitai_lora_json,
25
  download_my_lora_flux, get_all_lora_tupled_list, apply_lora_prompt_flux,
@@ -42,39 +44,33 @@ controlnet_model_union_repo = 'InstantX/FLUX.1-dev-Controlnet-Union'
42
  #controlnet_model_union_repo = 'Shakker-Labs/FLUX.1-dev-ControlNet-Union-Pro'
43
  dtype = torch.bfloat16
44
  #dtype = torch.float8_e4m3fn
45
- CACHE_MODEL = False
46
  device = "cuda" if torch.cuda.is_available() else "cpu"
47
  taef1 = AutoencoderTiny.from_pretrained("madebyollin/taef1", torch_dtype=dtype, token=HF_TOKEN)
48
  good_vae = AutoencoderKL.from_pretrained(base_model, subfolder="vae", torch_dtype=dtype, token=HF_TOKEN)
49
  pipe = DiffusionPipeline.from_pretrained(base_model, torch_dtype=dtype, vae=taef1, token=HF_TOKEN)
50
- if CACHE_MODEL:
51
- taef1.to(device)
52
- good_vae.to(device)
53
- pipe.to(device)
54
- pipe.transformer.to("cpu")
55
  pipe_i2i = AutoPipelineForImage2Image.from_pretrained(base_model, vae=good_vae, transformer=pipe.transformer, text_encoder=pipe.text_encoder,
56
  tokenizer=pipe.tokenizer, text_encoder_2=pipe.text_encoder_2, tokenizer_2=pipe.tokenizer_2, torch_dtype=dtype, token=HF_TOKEN)
57
- pipe_ip = AutoPipelineForInpainting.from_pretrained(base_model, vae=good_vae, transformer=pipe.transformer, text_encoder=pipe.text_encoder,
58
- tokenizer=pipe.tokenizer, text_encoder_2=pipe.text_encoder_2, tokenizer_2=pipe.tokenizer_2, torch_dtype=dtype, token=HF_TOKEN)
59
  controlnet_union = None
60
  controlnet = None
61
  last_model = models[0]
62
  last_cn_on = False
 
 
63
  #controlnet_union = FluxControlNetModel.from_pretrained(controlnet_model_union_repo, torch_dtype=dtype)
64
  #controlnet = FluxMultiControlNetModel([controlnet_union])
65
  #controlnet.config = controlnet_union.config
66
 
67
  MAX_SEED = 2**32-1
 
 
68
 
69
  def unload_lora():
70
- global pipe, pipe_i2i, pipe_ip
71
  try:
72
  #pipe.unfuse_lora()
73
  pipe.unload_lora_weights()
74
  #pipe_i2i.unfuse_lora()
75
  pipe_i2i.unload_lora_weights()
76
- #pipe_ip.unfuse_lora()
77
- pipe_ip.unload_lora_weights()
78
  except Exception as e:
79
  print(e)
80
 
@@ -83,90 +79,104 @@ def download_file_mod(url, directory=os.getcwd()):
83
  if not path: raise Exception(f"Download error: {url}")
84
  return path
85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  # https://huggingface.co/InstantX/FLUX.1-dev-Controlnet-Union
87
  # https://huggingface.co/spaces/jiuface/FLUX.1-dev-Controlnet-Union
88
  # https://huggingface.co/docs/diffusers/main/en/api/pipelines/flux
89
  #@spaces.GPU()
90
- def change_base_model(repo_id: str, cn_on: bool, disable_model_cache: bool, model_type: str, progress=gr.Progress(track_tqdm=True)):
91
- global pipe, pipe_i2i, pipe_ip, taef1, good_vae, controlnet_union, controlnet, last_model, last_cn_on, dtype
92
- safetensors_file = None
93
- single_file_base_model = single_file_base_models.get(model_type, models[0])
94
  try:
95
- #if not disable_model_cache and (repo_id == last_model and cn_on is last_cn_on) or not is_repo_name(repo_id) or not is_repo_exists(repo_id): return gr.update(visible=True)
96
- if not disable_model_cache and (repo_id == last_model and cn_on is last_cn_on) or ((not is_repo_name(repo_id) or not is_repo_exists(repo_id)) and not ".safetensors" in repo_id): return gr.update()
97
  unload_lora()
98
  pipe.to("cpu")
99
  pipe_i2i.to("cpu")
100
- pipe_ip.to("cpu")
101
  good_vae.to("cpu")
102
  taef1.to("cpu")
103
  if controlnet is not None: controlnet.to("cpu")
104
  if controlnet_union is not None: controlnet_union.to("cpu")
105
  clear_cache()
106
- if cn_on:
107
- progress(0, desc=f"Loading model: {repo_id} / Loading ControlNet: {controlnet_model_union_repo}")
108
- print(f"Loading model: {repo_id} / Loading ControlNet: {controlnet_model_union_repo}")
109
- controlnet_union = FluxControlNetModel.from_pretrained(controlnet_model_union_repo, torch_dtype=dtype, token=HF_TOKEN)
110
- controlnet = FluxMultiControlNetModel([controlnet_union])
111
- controlnet.config = controlnet_union.config
112
- if ".safetensors" in repo_id:
113
- safetensors_file = download_file_mod(repo_id)
114
- transformer = FluxTransformer2DModel.from_single_file(safetensors_file, subfolder="transformer", torch_dtype=dtype, config=single_file_base_model)
115
- if CACHE_MODEL:
116
- pipe = FluxControlNetPipeline.from_pretrained(single_file_base_model, controlnet=controlnet, vae=good_vae, transformer=transformer, text_encoder=pipe.text_encoder,
117
- tokenizer=pipe.tokenizer, text_encoder_2=pipe.text_encoder_2, tokenizer_2=pipe.tokenizer_2, torch_dtype=dtype, token=HF_TOKEN)
118
- else: pipe = FluxControlNetPipeline.from_pretrained(single_file_base_model, transformer=transformer, controlnet=controlnet, torch_dtype=dtype, token=HF_TOKEN)
119
- pipe_i2i = FluxControlNetImg2ImgPipeline.from_pretrained(single_file_base_model, controlnet=controlnet, vae=good_vae, transformer=pipe.transformer, text_encoder=pipe.text_encoder,
120
- tokenizer=pipe.tokenizer, text_encoder_2=pipe.text_encoder_2, tokenizer_2=pipe.tokenizer_2, torch_dtype=dtype, token=HF_TOKEN)
121
- pipe_ip = FluxControlNetInpaintPipeline.from_pretrained(single_file_base_model, controlnet=controlnet, vae=good_vae, transformer=pipe.transformer, text_encoder=pipe.text_encoder,
122
- tokenizer=pipe.tokenizer, text_encoder_2=pipe.text_encoder_2, tokenizer_2=pipe.tokenizer_2, torch_dtype=dtype, token=HF_TOKEN)
123
- else:
124
- if CACHE_MODEL:
125
- transformer = FluxTransformer2DModel.from_pretrained(repo_id, subfolder="transformer", torch_dtype=dtype, token=HF_TOKEN)
126
- pipe = FluxControlNetPipeline.from_pretrained(repo_id, controlnet=controlnet, vae=good_vae, transformer=transformer, text_encoder=pipe.text_encoder,
127
- tokenizer=pipe.tokenizer, text_encoder_2=pipe.text_encoder_2, tokenizer_2=pipe.tokenizer_2, torch_dtype=dtype, token=HF_TOKEN)
128
- pipe = FluxControlNetPipeline.from_pretrained(repo_id, controlnet=controlnet, torch_dtype=dtype, token=HF_TOKEN)
129
- pipe_i2i = FluxControlNetImg2ImgPipeline.from_pretrained(repo_id, controlnet=controlnet, vae=good_vae, transformer=pipe.transformer, text_encoder=pipe.text_encoder,
130
- tokenizer=pipe.tokenizer, text_encoder_2=pipe.text_encoder_2, tokenizer_2=pipe.tokenizer_2, torch_dtype=dtype, token=HF_TOKEN)
131
- pipe_ip = FluxControlNetInpaintPipeline.from_pretrained(repo_id, controlnet=controlnet, vae=good_vae, transformer=pipe.transformer, text_encoder=pipe.text_encoder,
132
- tokenizer=pipe.tokenizer, text_encoder_2=pipe.text_encoder_2, tokenizer_2=pipe.tokenizer_2, torch_dtype=dtype, token=HF_TOKEN)
133
- last_model = repo_id
134
- last_cn_on = cn_on
135
- progress(1, desc=f"Model loaded: {repo_id} / ControlNet Loaded: {controlnet_model_union_repo}")
136
- print(f"Model loaded: {repo_id} / ControlNet Loaded: {controlnet_model_union_repo}")
137
- else:
138
- progress(0, desc=f"Loading model: {repo_id}")
139
- print(f"Loading model: {repo_id}")
140
- if ".safetensors" in repo_id:
141
- safetensors_file = download_file_mod(repo_id)
142
- transformer = FluxTransformer2DModel.from_single_file(safetensors_file, subfolder="transformer", torch_dtype=dtype, config=single_file_base_model, token=HF_TOKEN)
143
- if CACHE_MODEL:
144
- pipe = DiffusionPipeline.from_pretrained(single_file_base_model, vae=taef1, transformer=transformer, text_encoder=pipe.text_encoder,
145
- tokenizer=pipe.tokenizer, text_encoder_2=pipe.text_encoder_2, tokenizer_2=pipe.tokenizer_2, torch_dtype=dtype, token=HF_TOKEN)
146
- else: pipe = DiffusionPipeline.from_pretrained(single_file_base_model, transformer=transformer, torch_dtype=dtype, token=HF_TOKEN)
147
- pipe_i2i = AutoPipelineForImage2Image.from_pretrained(single_file_base_model, vae=good_vae, transformer=pipe.transformer, text_encoder=pipe.text_encoder,
148
- tokenizer=pipe.tokenizer, text_encoder_2=pipe.text_encoder_2, tokenizer_2=pipe.tokenizer_2, torch_dtype=dtype, token=HF_TOKEN)
149
- pipe_ip = AutoPipelineForInpainting.from_pretrained(single_file_base_model, vae=good_vae, transformer=pipe.transformer, text_encoder=pipe.text_encoder,
150
- tokenizer=pipe.tokenizer, text_encoder_2=pipe.text_encoder_2, tokenizer_2=pipe.tokenizer_2, torch_dtype=dtype, token=HF_TOKEN)
151
- else:
152
- if CACHE_MODEL:
153
- transformer = FluxTransformer2DModel.from_pretrained(repo_id, subfolder="transformer", torch_dtype=dtype, token=HF_TOKEN)
154
- pipe = DiffusionPipeline.from_pretrained(repo_id, vae=taef1, transformer=transformer, text_encoder=pipe.text_encoder,
155
- tokenizer=pipe.tokenizer, text_encoder_2=pipe.text_encoder_2, tokenizer_2=pipe.tokenizer_2, torch_dtype=dtype, token=HF_TOKEN)
156
- else: pipe = DiffusionPipeline.from_pretrained(repo_id, torch_dtype=dtype, token=HF_TOKEN)
157
- pipe_i2i = AutoPipelineForImage2Image.from_pretrained(repo_id, vae=good_vae, transformer=pipe.transformer, text_encoder=pipe.text_encoder,
158
- tokenizer=pipe.tokenizer, text_encoder_2=pipe.text_encoder_2, tokenizer_2=pipe.tokenizer_2, torch_dtype=dtype, token=HF_TOKEN)
159
- pipe_ip = AutoPipelineForInpainting.from_pretrained(repo_id, vae=good_vae, transformer=pipe.transformer, text_encoder=pipe.text_encoder,
160
- tokenizer=pipe.tokenizer, text_encoder_2=pipe.text_encoder_2, tokenizer_2=pipe.tokenizer_2, torch_dtype=dtype, token=HF_TOKEN)
161
- last_model = repo_id
162
- last_cn_on = cn_on
163
- progress(1, desc=f"Model loaded: {repo_id}")
164
- print(f"Model loaded: {repo_id}")
165
  except Exception as e:
166
  print(f"Model load Error: {repo_id} {e}")
167
  raise gr.Error(f"Model load Error: {repo_id} {e}") from e
168
- finally:
169
- if safetensors_file and Path(safetensors_file).exists(): Path(safetensors_file).unlink()
170
  return gr.update()
171
 
172
  change_base_model.zerogpu = True
@@ -441,7 +451,7 @@ def remove_custom_lora(selected_indices, current_loras, gallery):
441
 
442
  @spaces.GPU(duration=70)
443
  @torch.inference_mode()
444
- def generate_image(prompt_mash, steps, seed, cfg_scale, width, height, sigmas_factor, cn_on, progress=gr.Progress(track_tqdm=True)):
445
  global pipe, taef1, good_vae, controlnet, controlnet_union
446
  try:
447
  good_vae.to(device)
@@ -452,11 +462,11 @@ def generate_image(prompt_mash, steps, seed, cfg_scale, width, height, sigmas_fa
452
  with calculateDuration("Generating image"):
453
  # Generate image
454
  modes, images, scales = get_control_params()
455
- if not cn_on or len(modes) == 0:
456
  pipe.to(device)
457
  pipe.vae = taef1
458
  pipe.flux_pipe_call_that_returns_an_iterable_of_images = flux_pipe_call_that_returns_an_iterable_of_images.__get__(pipe)
459
- progress(0, desc="Start Inference.")
460
  for img in pipe.flux_pipe_call_that_returns_an_iterable_of_images(
461
  prompt=prompt_mash,
462
  num_inference_steps=steps,
@@ -470,13 +480,13 @@ def generate_image(prompt_mash, steps, seed, cfg_scale, width, height, sigmas_fa
470
  sigmas=sigmas,
471
  ):
472
  yield img
473
- else:
474
  pipe.to(device)
475
  pipe.vae = good_vae
476
  if controlnet_union is not None: controlnet_union.to(device)
477
  if controlnet is not None: controlnet.to(device)
478
  pipe.enable_model_cpu_offload()
479
- progress(0, desc="Start Inference with ControlNet.")
480
  for img in pipe(
481
  prompt=prompt_mash,
482
  control_image=images,
@@ -497,122 +507,94 @@ def generate_image(prompt_mash, steps, seed, cfg_scale, width, height, sigmas_fa
497
 
498
  @spaces.GPU(duration=70)
499
  @torch.inference_mode()
500
- def generate_image_to_image(prompt_mash, image_input_path_dict, image_strength, is_inpaint, blur_mask, blur_factor, steps, cfg_scale, width, height,
501
- sigmas_factor, seed, cn_on, progress=gr.Progress(track_tqdm=True)):
502
- global pipe_i2i, pipe_ip, good_vae, controlnet, controlnet_union
503
  try:
504
  good_vae.to(device)
505
  generator = torch.Generator(device=device).manual_seed(int(float(seed)))
506
  image_input_path = image_input_path_dict['background']
507
  mask_path = image_input_path_dict['layers'][0]
508
- sigmas = calc_sigmas(steps, sigmas_factor)
 
 
 
 
 
 
509
 
510
  with calculateDuration("Generating image"):
511
  # Generate image
512
  modes, images, scales = get_control_params()
513
- if not cn_on or len(modes) == 0:
514
- if is_inpaint: # Inpainting
515
- pipe_ip.to(device)
516
- pipe_ip.vae = good_vae
517
- image_input = load_image(image_input_path)
518
  mask_input = load_image(mask_path)
519
- if blur_mask: mask_input = pipe_ip.mask_processor.blur(mask_input, blur_factor=blur_factor)
520
- progress(0, desc="Start Inpainting Inference.")
521
- final_image = pipe_ip(
522
- prompt=prompt_mash,
523
- image=image_input,
524
- mask_image=mask_input,
525
- strength=image_strength,
526
- num_inference_steps=steps,
527
- guidance_scale=cfg_scale,
528
- width=width,
529
- height=height,
530
- generator=generator,
531
- joint_attention_kwargs={"scale": 1.0},
532
- output_type="pil",
533
- #sigmas=sigmas,
534
- ).images[0]
535
- return final_image
536
- else:
537
- pipe_i2i.to(device)
538
- pipe_i2i.vae = good_vae
539
- image_input = load_image(image_input_path)
540
- progress(0, desc="Start I2I Inference.")
541
- final_image = pipe_i2i(
542
- prompt=prompt_mash,
543
- image=image_input,
544
- strength=image_strength,
545
- num_inference_steps=steps,
546
- guidance_scale=cfg_scale,
547
- width=width,
548
- height=height,
549
- generator=generator,
550
- joint_attention_kwargs={"scale": 1.0},
551
- output_type="pil",
552
- #sigmas=sigmas,
553
- ).images[0]
554
- return final_image
555
- else:
556
- if is_inpaint: # Inpainting
557
- pipe_ip.to(device)
558
- pipe_ip.vae = good_vae
559
- image_input = load_image(image_input_path)
560
  mask_input = load_image(mask_path)
561
- if blur_mask: mask_input = pipe_ip.mask_processor.blur(mask_input, blur_factor=blur_factor)
562
- if controlnet_union is not None: controlnet_union.to(device)
563
- if controlnet is not None: controlnet.to(device)
564
- pipe_ip.enable_model_cpu_offload()
565
- progress(0, desc="Start Inpainting Inference with ControlNet.")
566
- final_image = pipe_ip(
567
- prompt=prompt_mash,
568
- control_image=images,
569
- control_mode=modes,
570
- image=image_input,
571
- mask_image=mask_input,
572
- strength=image_strength,
573
- num_inference_steps=steps,
574
- guidance_scale=cfg_scale,
575
- width=width,
576
- height=height,
577
- controlnet_conditioning_scale=scales,
578
- generator=generator,
579
- joint_attention_kwargs={"scale": 1.0},
580
- output_type="pil",
581
- #sigmas=sigmas,
582
- ).images[0]
583
- return final_image
584
- else:
585
- pipe_i2i.to(device)
586
- pipe_i2i.vae = good_vae
587
- image_input = load_image(image_input_path['background'])
588
- if controlnet_union is not None: controlnet_union.to(device)
589
- if controlnet is not None: controlnet.to(device)
590
- pipe_i2i.enable_model_cpu_offload()
591
- progress(0, desc="Start I2I Inference with ControlNet.")
592
- final_image = pipe_i2i(
593
- prompt=prompt_mash,
594
- control_image=images,
595
- control_mode=modes,
596
- image=image_input,
597
- strength=image_strength,
598
- num_inference_steps=steps,
599
- guidance_scale=cfg_scale,
600
- width=width,
601
- height=height,
602
- controlnet_conditioning_scale=scales,
603
- generator=generator,
604
- joint_attention_kwargs={"scale": 1.0},
605
- output_type="pil",
606
- #sigmas=sigmas,
607
- ).images[0]
608
- return final_image
609
  except Exception as e:
610
  print(e)
611
  raise gr.Error(f"I2I Inference Error: {e}") from e
612
 
613
- def run_lora(prompt, image_input, image_strength, task_type, blur_mask, blur_factor, cfg_scale, steps, selected_indices, lora_scale_1, lora_scale_2,
614
- randomize_seed, seed, width, height, sigmas_factor, loras_state, lora_json, cn_on, translate_on, progress=gr.Progress(track_tqdm=True)):
615
- global pipe, pipe_i2i, pipe_ip
 
 
616
  if not selected_indices and not is_valid_lora(lora_json):
617
  gr.Info("LoRA isn't selected.")
618
  # raise gr.Error("You must select a LoRA before proceeding.")
@@ -620,16 +602,8 @@ def run_lora(prompt, image_input, image_strength, task_type, blur_mask, blur_fac
620
 
621
  selected_loras = [loras_state[idx] for idx in selected_indices]
622
 
623
- if task_type == "Inpainting":
624
- is_inpaint = True
625
- is_i2i = True
626
- elif task_type == "Image-to-Image":
627
- is_inpaint = False
628
- is_i2i = True
629
- else: # "Text-to-Image"
630
- is_inpaint = False
631
- is_i2i = False
632
-
633
  if translate_on: prompt = translate_to_en(prompt)
634
 
635
  # Build the prompt with trigger words
@@ -651,7 +625,6 @@ def run_lora(prompt, image_input, image_strength, task_type, blur_mask, blur_fac
651
 
652
  print(pipe.get_active_adapters()) #
653
  print(pipe_i2i.get_active_adapters()) #
654
- print(pipe_ip.get_active_adapters()) #
655
 
656
  clear_cache() #
657
 
@@ -659,13 +632,16 @@ def run_lora(prompt, image_input, image_strength, task_type, blur_mask, blur_fac
659
  prompt_mash = prompt_mash + get_model_trigger(last_model)
660
  lora_names = []
661
  lora_weights = []
662
- if is_valid_lora(lora_json): # Load External LoRA weights
 
 
 
 
 
 
663
  with calculateDuration("Loading External LoRA weights"):
664
- if is_inpaint:
665
- pipe_ip, lora_names, lora_weights = fuse_loras(pipe_ip, lora_json)
666
- elif is_i2i:
667
- pipe_i2i, lora_names, lora_weights = fuse_loras(pipe_i2i, lora_json)
668
- else: pipe, lora_names, lora_weights = fuse_loras(pipe, lora_json)
669
  trigger_word = get_trigger_word(lora_json)
670
  prompt_mash = f"{prompt_mash} {trigger_word}"
671
  print("Prompt Mash: ", prompt_mash) #
@@ -681,15 +657,7 @@ def run_lora(prompt, image_input, image_strength, task_type, blur_mask, blur_fac
681
  lora_path = lora['repo']
682
  weight_name = lora.get("weights")
683
  print(f"Lora Path: {lora_path}")
684
- if is_inpaint:
685
- pipe_ip.load_lora_weights(
686
- lora_path,
687
- weight_name=weight_name if weight_name else None,
688
- low_cpu_mem_usage=False,
689
- adapter_name=lora_name,
690
- token=HF_TOKEN
691
- )
692
- elif is_i2i:
693
  pipe_i2i.load_lora_weights(
694
  lora_path,
695
  weight_name=weight_name if weight_name else None,
@@ -707,16 +675,11 @@ def run_lora(prompt, image_input, image_strength, task_type, blur_mask, blur_fac
707
  )
708
  print("Loaded LoRAs:", lora_names)
709
  if selected_indices or is_valid_lora(lora_json):
710
- if is_inpaint:
711
- pipe_ip.set_adapters(lora_names, adapter_weights=lora_weights)
712
- elif is_i2i:
713
- pipe_i2i.set_adapters(lora_names, adapter_weights=lora_weights)
714
- else:
715
- pipe.set_adapters(lora_names, adapter_weights=lora_weights)
716
 
717
  print(pipe.get_active_adapters()) #
718
  print(pipe_i2i.get_active_adapters()) #
719
- print(pipe_ip.get_active_adapters()) #
720
 
721
  # Set random seed for reproducibility
722
  with calculateDuration("Randomizing seed"):
@@ -726,7 +689,7 @@ def run_lora(prompt, image_input, image_strength, task_type, blur_mask, blur_fac
726
  # Generate image
727
  progress(0, desc="Running Inference.")
728
  if is_i2i:
729
- final_image = generate_image_to_image(prompt_mash, image_input, image_strength, is_inpaint, blur_mask, blur_factor,
730
  steps, cfg_scale, width, height, sigmas_factor, seed, cn_on)
731
  yield save_image(final_image, None, last_model, prompt_mash, height, width, steps, cfg_scale, seed), seed, gr.update(visible=False)
732
  else:
@@ -898,7 +861,6 @@ with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', fill_width=True, css=css, delete_ca
898
  show_share_button=False, show_download_button=True)
899
  history_clear_button = gr.Button(value="Clear History", variant="secondary")
900
  history_clear_button.click(lambda: ([], []), None, [history_gallery, history_files], queue=False, show_api=False)
901
-
902
  with gr.Row():
903
  with gr.Accordion("Advanced Settings", open=True):
904
  with gr.Tab("Generation Settings"):
@@ -906,9 +868,9 @@ with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', fill_width=True, css=css, delete_ca
906
  with gr.Group():
907
  with gr.Row():
908
  model_name = gr.Dropdown(label="Base Model", info="You can enter a huggingface model repo_id or path of single safetensors file to want to use.",
909
- choices=models, value=models[0], allow_custom_value=True, min_width=320, scale=5)
910
  model_type = gr.Radio(label="Model type", info="Model type of single safetensors file",
911
- choices=list(single_file_base_models.keys()), value=list(single_file_base_models.keys())[0], scale=1)
912
  model_info = gr.Markdown(elem_classes="info")
913
  with gr.Row():
914
  width = gr.Slider(label="Width", minimum=256, maximum=1536, step=64, value=1024)
@@ -918,17 +880,21 @@ with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', fill_width=True, css=css, delete_ca
918
  with gr.Row():
919
  randomize_seed = gr.Checkbox(True, label="Randomize seed")
920
  seed = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=0, randomize=True)
 
 
921
  sigmas_factor = gr.Slider(label="Sigmas factor", minimum=0.01, maximum=1.00, step=0.01, value=0.95)
 
922
  disable_model_cache = gr.Checkbox(False, label="Disable model caching")
923
  with gr.Tab("Image-to-Image"):
924
  with gr.Row():
925
  with gr.Column():
926
  #input_image = gr.Image(label="Input image", type="filepath", height=256, sources=["upload", "clipboard"], show_share_button=False)
927
  input_image = gr.ImageEditor(label='Input image', type='filepath', sources=["upload", "clipboard"], image_mode='RGB', show_share_button=False, show_fullscreen_button=False,
928
- layers=False, brush=gr.Brush(colors=["white"], color_mode="fixed", default_size=32), eraser=gr.Eraser(default_size="32"), value=None,
929
- canvas_size=(384, 384), width=384, height=512)
930
  with gr.Column():
931
- task_type = gr.Radio(label="Task", choices=["Text-to-Image", "Image-to-Image", "Inpainting"], value="Text-to-Image")
 
932
  image_strength = gr.Slider(label="Strength", info="Lower means more image influence in I2I, opposite in Inpaint", minimum=0.01, maximum=1.0, step=0.01, value=0.75)
933
  blur_mask = gr.Checkbox(label="Blur mask", value=False)
934
  blur_factor = gr.Slider(label="Blur factor", minimum=0, maximum=50, step=1, value=33)
@@ -1033,27 +999,23 @@ with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', fill_width=True, css=css, delete_ca
1033
  gr.on(
1034
  triggers=[generate_button.click, prompt.submit],
1035
  fn=change_base_model,
1036
- inputs=[model_name, cn_on, disable_model_cache, model_type],
1037
  outputs=[result],
1038
  queue=True,
1039
  show_api=False,
1040
  trigger_mode="once",
1041
  ).success(
1042
  fn=run_lora,
1043
- inputs=[prompt, input_image, image_strength, task_type, blur_mask, blur_factor, cfg_scale, steps, selected_indices, lora_scale_1, lora_scale_2,
1044
  randomize_seed, seed, width, height, sigmas_factor, loras_state, lora_repo_json, cn_on, auto_trans],
1045
  outputs=[result, seed, progress_bar],
1046
  queue=True,
1047
  show_api=True,
1048
- #).then( # Update the history gallery
1049
- # fn=lambda x, history: update_history(x, history),
1050
- # inputs=[result, history_gallery],
1051
- # outputs=history_gallery,
1052
  ).success(save_image_history, [result, history_gallery, history_files, model_name], [history_gallery, history_files], queue=False, show_api=False)
1053
 
1054
  input_image.clear(lambda: gr.update(value="Text-to-Image"), None, [task_type], queue=False, show_api=False)
1055
- input_image.upload(preprocess_i2i_image, [input_image, input_image_preprocess, height, width], [input_image], queue=False, show_api=False)\
1056
- .success(lambda: gr.update(value="Image-to-Image"), None, [task_type], queue=False, show_api=False)
1057
  gr.on(
1058
  triggers=[model_name.change, cn_on.change],
1059
  fn=get_t2i_model_info,
@@ -1062,7 +1024,7 @@ with gr.Blocks(theme='NoCrypt/miku@>=1.2.2', fill_width=True, css=css, delete_ca
1062
  queue=False,
1063
  show_api=False,
1064
  trigger_mode="once",
1065
- )#.then(change_base_model, [model_name, cn_on, disable_model_cache, model_type], [result], queue=True, show_api=False)
1066
  prompt_enhance.click(enhance_prompt, [prompt], [prompt], queue=False, show_api=False)
1067
 
1068
  gr.on(
 
2
  import gradio as gr
3
  import json
4
  import torch
5
+ from diffusers import DiffusionPipeline, AutoencoderTiny, AutoencoderKL, AutoPipelineForImage2Image, AutoPipelineForInpainting, GGUFQuantizationConfig
6
  from live_preview_helpers import calculate_shift, retrieve_timesteps, flux_pipe_call_that_returns_an_iterable_of_images
7
  from diffusers.utils import load_image
8
+ from diffusers import (FluxControlNetPipeline, FluxControlNetModel, FluxMultiControlNetModel, FluxControlNetImg2ImgPipeline,
9
+ FluxTransformer2DModel, FluxControlNetInpaintPipeline, FluxImg2ImgPipeline, FluxInpaintPipeline, FluxFillPipeline, FluxControlPipeline)
10
+ from transformers import T5EncoderModel
11
  from huggingface_hub import hf_hub_download, HfFileSystem, ModelCard, snapshot_download, HfApi
12
  import os
13
  import copy
 
18
  import numpy as np
19
  from pathlib import Path
20
 
21
+ from env import models, models_dev, models_schnell, models_fill, models_canny, models_depth, num_loras, num_cns, HF_TOKEN, single_file_base_models
22
  from mod import (clear_cache, get_repo_safetensors, is_repo_name, is_repo_exists, get_model_trigger,
23
+ description_ui, compose_lora_json, is_valid_lora, fuse_loras, turbo_loras, save_image, preprocess_i2i_image,
24
+ get_trigger_word, enhance_prompt, set_control_union_image, get_canny_image, get_depth_image,
25
  get_control_union_mode, set_control_union_mode, get_control_params, translate_to_en)
26
  from modutils import (search_civitai_lora, select_civitai_lora, search_civitai_lora_json,
27
  download_my_lora_flux, get_all_lora_tupled_list, apply_lora_prompt_flux,
 
44
  #controlnet_model_union_repo = 'Shakker-Labs/FLUX.1-dev-ControlNet-Union-Pro'
45
  dtype = torch.bfloat16
46
  #dtype = torch.float8_e4m3fn
 
47
  device = "cuda" if torch.cuda.is_available() else "cpu"
48
  taef1 = AutoencoderTiny.from_pretrained("madebyollin/taef1", torch_dtype=dtype, token=HF_TOKEN)
49
  good_vae = AutoencoderKL.from_pretrained(base_model, subfolder="vae", torch_dtype=dtype, token=HF_TOKEN)
50
  pipe = DiffusionPipeline.from_pretrained(base_model, torch_dtype=dtype, vae=taef1, token=HF_TOKEN)
 
 
 
 
 
51
  pipe_i2i = AutoPipelineForImage2Image.from_pretrained(base_model, vae=good_vae, transformer=pipe.transformer, text_encoder=pipe.text_encoder,
52
  tokenizer=pipe.tokenizer, text_encoder_2=pipe.text_encoder_2, tokenizer_2=pipe.tokenizer_2, torch_dtype=dtype, token=HF_TOKEN)
 
 
53
  controlnet_union = None
54
  controlnet = None
55
  last_model = models[0]
56
  last_cn_on = False
57
+ last_task = "Text-to-Image"
58
+ last_dtype_str = "BF16"
59
  #controlnet_union = FluxControlNetModel.from_pretrained(controlnet_model_union_repo, torch_dtype=dtype)
60
  #controlnet = FluxMultiControlNetModel([controlnet_union])
61
  #controlnet.config = controlnet_union.config
62
 
63
  MAX_SEED = 2**32-1
64
+ TASK_TYPE_T2I = ["Text-to-Image"]
65
+ TASK_TYPE_I2I = ["Image-to-Image", "Inpainting", "Flux Fill"] # , "Canny", "Depth"
66
 
67
  def unload_lora():
68
+ global pipe, pipe_i2i
69
  try:
70
  #pipe.unfuse_lora()
71
  pipe.unload_lora_weights()
72
  #pipe_i2i.unfuse_lora()
73
  pipe_i2i.unload_lora_weights()
 
 
74
  except Exception as e:
75
  print(e)
76
 
 
79
  if not path: raise Exception(f"Download error: {url}")
80
  return path
81
 
82
+ def print_progress(desc: str, proceed: float=0.0, progress=gr.Progress(track_tqdm=True)):
83
+ progress(proceed, desc=desc)
84
+ print(desc)
85
+
86
+ #@spaces.GPU(duration=30)
87
+ def load_quantized_control(control_repo: str, dtype, hf_token):
88
+ transformer = FluxTransformer2DModel.from_pretrained(control_repo, subfolder="transformer", torch_dtype=dtype, token=hf_token).to("cpu")
89
+ text_encoder_2 = T5EncoderModel.from_pretrained(control_repo, subfolder="text_encoder_2", torch_dtype=dtype, token=hf_token).to("cpu")
90
+ return transformer, text_encoder_2
91
+
92
+ def load_pipeline(repo_id: str, cn_on: bool, model_type: str, task: str, dtype_str: str, hf_token: str, progress=gr.Progress(track_tqdm=True)):
93
+ pipe = None
94
+ pipe_i2i = None
95
+ try:
96
+ controlnet_model_union_repo = 'InstantX/FLUX.1-dev-Controlnet-Union'
97
+ if task == "Flux Fill" or repo_id in models_fill:
98
+ model_type = "fill"
99
+ if repo_id in set(models_dev + models_schnell): repo_id = models_fill[0]
100
+ if dtype_str == "BF16": dtype = torch.bfloat16
101
+ else: dtype = torch.bfloat16
102
+ single_file_base_model = single_file_base_models.get(model_type, models[0])
103
+ kwargs = {}
104
+ transformer_model = FluxTransformer2DModel
105
+ t5_model = T5EncoderModel
106
+ if task == "Flux Fill":
107
+ pipeline = FluxFillPipeline
108
+ pipeline_i2i = FluxFillPipeline
109
+ elif task == "Canny" or task == "Depth":
110
+ pipeline = DiffusionPipeline
111
+ pipeline_i2i = FluxControlPipeline
112
+ elif cn_on: # with ControlNet
113
+ print_progress(f"Loading model: {repo_id} / Loading ControlNet: {controlnet_model_union_repo}", 0, progress)
114
+ controlnet_union = FluxControlNetModel.from_pretrained(controlnet_model_union_repo, torch_dtype=dtype, token=hf_token)
115
+ controlnet = FluxMultiControlNetModel([controlnet_union])
116
+ controlnet.config = controlnet_union.config
117
+ pipeline = FluxControlNetPipeline
118
+ pipeline_i2i = FluxControlNetInpaintPipeline if task == "Inpainting" else FluxControlNetImg2ImgPipeline
119
+ kwargs["controlnet"] = controlnet
120
+ else: # without ControlNet
121
+ print_progress(f"Loading model: {repo_id}", 0, progress)
122
+ pipeline = DiffusionPipeline
123
+ pipeline_i2i = AutoPipelineForInpainting if task == "Inpainting" else AutoPipelineForImage2Image
124
+ if task == "Canny" or task == "Depth": # FluxControlPipeline
125
+ if task == "Canny": control_repo = models_canny[0]
126
+ elif task == "Depth": control_repo = models_depth[0]
127
+ transformer = transformer_model.from_pretrained(control_repo, subfolder="transformer", torch_dtype=dtype, token=hf_token)
128
+ text_encoder_2 = t5_model.from_pretrained(control_repo, subfolder="text_encoder_2", torch_dtype=dtype, token=hf_token)
129
+ #transformer, text_encoder_2 = load_quantized_control(control_repo, dtype, hf_token)
130
+ pipe = pipeline.from_pretrained(models_dev[0], transformer=transformer, text_encoder_2=text_encoder_2, torch_dtype=dtype, token=hf_token)
131
+ pipe_i2i = pipeline_i2i.from_pipe(pipe, transformer=transformer, text_encoder_2=text_encoder_2, torch_dtype=dtype)
132
+ elif ".safetensors" in repo_id or ".gguf" in repo_id: # from single file
133
+ file_url = repo_id.replace("/resolve/main/", "/blob/main/").replace("?download=true", "")
134
+ if ".gguf" in file_url: transformer_model.from_single_file(file_url, subfolder="transformer",
135
+ quantization_config=GGUFQuantizationConfig(compute_dtype=dtype), torch_dtype=dtype, config=single_file_base_model)
136
+ else: transformer = transformer_model.from_single_file(file_url, subfolder="transformer", torch_dtype=dtype, config=single_file_base_model)
137
+ pipe = pipeline.from_pretrained(single_file_base_model, transformer=transformer, torch_dtype=dtype, token=hf_token, **kwargs)
138
+ pipe_i2i = pipeline_i2i.from_pretrained(single_file_base_model, vae=pipe.vae, transformer=pipe.transformer,
139
+ text_encoder=pipe.text_encoder, tokenizer=pipe.tokenizer, text_encoder_2=pipe.text_encoder_2, tokenizer_2=pipe.tokenizer_2,
140
+ torch_dtype=dtype, token=hf_token, **kwargs)
141
+ else: # from diffusers repo
142
+ pipe = pipeline.from_pretrained(repo_id, torch_dtype=dtype, token=hf_token, **kwargs)
143
+ pipe_i2i = pipeline_i2i.from_pretrained(repo_id, vae=pipe.vae, transformer=pipe.transformer, text_encoder=pipe.text_encoder,
144
+ tokenizer=pipe.tokenizer, text_encoder_2=pipe.text_encoder_2, tokenizer_2=pipe.tokenizer_2, torch_dtype=dtype, token=hf_token, **kwargs)
145
+ if cn_on: print_progress(f"Model loaded: {repo_id} / ControlNet Loaded: {controlnet_model_union_repo}", 1, progress)
146
+ else: print_progress(f"Model loaded: {repo_id}", 1, progress)
147
+ except Exception as e:
148
+ print(e)
149
+ gr.Warning(f"Failed to load pipeline: {e}")
150
+ finally:
151
+ return pipe, pipe_i2i
152
+
153
+ #load_pipeline.zerogpu = True
154
+
155
  # https://huggingface.co/InstantX/FLUX.1-dev-Controlnet-Union
156
  # https://huggingface.co/spaces/jiuface/FLUX.1-dev-Controlnet-Union
157
  # https://huggingface.co/docs/diffusers/main/en/api/pipelines/flux
158
  #@spaces.GPU()
159
+ def change_base_model(repo_id: str, cn_on: bool, disable_model_cache: bool, model_type: str, task: str, dtype_str: str, progress=gr.Progress(track_tqdm=True)):
160
+ global pipe, pipe_i2i, taef1, good_vae, controlnet_union, controlnet, last_model, last_cn_on, last_task, last_dtype_str, dtype
 
 
161
  try:
162
+ if not disable_model_cache and (repo_id == last_model and cn_on is last_cn_on and task == last_task and dtype_str == last_dtype_str)\
163
+ or ((not is_repo_name(repo_id) or not is_repo_exists(repo_id)) and not ".safetensors" in repo_id): return gr.update()
164
  unload_lora()
165
  pipe.to("cpu")
166
  pipe_i2i.to("cpu")
 
167
  good_vae.to("cpu")
168
  taef1.to("cpu")
169
  if controlnet is not None: controlnet.to("cpu")
170
  if controlnet_union is not None: controlnet_union.to("cpu")
171
  clear_cache()
172
+ pipe, pipe_i2i = load_pipeline(repo_id, cn_on, model_type, task, dtype_str, HF_TOKEN, progress)
173
+ last_model = repo_id
174
+ last_cn_on = cn_on
175
+ last_task = task
176
+ last_dtype_str = dtype_str
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  except Exception as e:
178
  print(f"Model load Error: {repo_id} {e}")
179
  raise gr.Error(f"Model load Error: {repo_id} {e}") from e
 
 
180
  return gr.update()
181
 
182
  change_base_model.zerogpu = True
 
451
 
452
  @spaces.GPU(duration=70)
453
  @torch.inference_mode()
454
+ def generate_image(prompt_mash: str, steps: int, seed: int, cfg_scale: float, width: int, height: int, sigmas_factor: float, cn_on: bool, progress=gr.Progress(track_tqdm=True)):
455
  global pipe, taef1, good_vae, controlnet, controlnet_union
456
  try:
457
  good_vae.to(device)
 
462
  with calculateDuration("Generating image"):
463
  # Generate image
464
  modes, images, scales = get_control_params()
465
+ if not cn_on or len(modes) == 0: # without ControlNet
466
  pipe.to(device)
467
  pipe.vae = taef1
468
  pipe.flux_pipe_call_that_returns_an_iterable_of_images = flux_pipe_call_that_returns_an_iterable_of_images.__get__(pipe)
469
+ print_progress("Start Inference.")
470
  for img in pipe.flux_pipe_call_that_returns_an_iterable_of_images(
471
  prompt=prompt_mash,
472
  num_inference_steps=steps,
 
480
  sigmas=sigmas,
481
  ):
482
  yield img
483
+ else: # with ControlNet
484
  pipe.to(device)
485
  pipe.vae = good_vae
486
  if controlnet_union is not None: controlnet_union.to(device)
487
  if controlnet is not None: controlnet.to(device)
488
  pipe.enable_model_cpu_offload()
489
+ print_progress("Start Inference with ControlNet.")
490
  for img in pipe(
491
  prompt=prompt_mash,
492
  control_image=images,
 
507
 
508
  @spaces.GPU(duration=70)
509
  @torch.inference_mode()
510
+ def generate_image_to_image(prompt_mash: str, image_input_path_dict: dict, image_strength: float, task_type: str, blur_mask: bool, blur_factor: float,
511
+ steps: int, cfg_scale: float, width: int, height: int, sigmas_factor: float, seed: int, cn_on: bool, progress=gr.Progress(track_tqdm=True)):
512
+ global pipe_i2i, good_vae, controlnet, controlnet_union
513
  try:
514
  good_vae.to(device)
515
  generator = torch.Generator(device=device).manual_seed(int(float(seed)))
516
  image_input_path = image_input_path_dict['background']
517
  mask_path = image_input_path_dict['layers'][0]
518
+ is_mask = True if task_type == "Inpainting" or task_type == "Flux Fill" else False
519
+ is_fill = True if task_type == "Flux Fill" else False
520
+ is_depth = True if task_type == "Depth" else False
521
+ is_canny = True if task_type == "Canny" else False
522
+ kwargs = {}
523
+ if not is_fill: kwargs["strength"] = image_strength
524
+ if sigmas_factor < 1.0 and task_type != "Image-to-Image": kwargs["sigmas"] = calc_sigmas(steps, sigmas_factor)
525
 
526
  with calculateDuration("Generating image"):
527
  # Generate image
528
  modes, images, scales = get_control_params()
529
+ if not cn_on or len(modes) == 0: # without ControlNet
530
+ pipe_i2i.to(device)
531
+ pipe_i2i.vae = good_vae
532
+ image_input = load_image(image_input_path)
533
+ if is_mask:
534
  mask_input = load_image(mask_path)
535
+ if blur_mask: mask_input = pipe_i2i.mask_processor.blur(mask_input, blur_factor=blur_factor)
536
+ kwargs["mask_image"] = mask_input
537
+ if is_fill: print_progress("Start Flux Fill Inference.")
538
+ else: print_progress("Start Inpainting Inference.")
539
+ elif is_canny:
540
+ image_input = get_canny_image(image_input, height, width)
541
+ print_progress("Start Canny Inference.")
542
+ elif is_depth:
543
+ image_input = get_depth_image(image_input, height, width)
544
+ print_progress("Start Depth Inference.")
545
+ else: print_progress("Start I2I Inference.")
546
+ final_image = pipe_i2i(
547
+ prompt=prompt_mash,
548
+ image=image_input,
549
+ num_inference_steps=steps,
550
+ guidance_scale=cfg_scale,
551
+ #width=width,
552
+ #height=height,
553
+ generator=generator,
554
+ joint_attention_kwargs={"scale": 1.0},
555
+ output_type="pil",
556
+ **kwargs,
557
+ ).images[0]
558
+ return final_image
559
+ else: # with ControlNet
560
+ pipe_i2i.to(device)
561
+ pipe_i2i.vae = good_vae
562
+ image_input = load_image(image_input_path)
563
+ if controlnet_union is not None: controlnet_union.to(device)
564
+ if controlnet is not None: controlnet.to(device)
565
+ if is_mask:
 
 
 
 
 
 
 
 
 
 
566
  mask_input = load_image(mask_path)
567
+ if blur_mask: mask_input = pipe_i2i.mask_processor.blur(mask_input, blur_factor=blur_factor)
568
+ kwargs["mask_image"] = mask_input
569
+ if is_fill: print_progress("Start Flux Fill Inference with ControlNet.")
570
+ else: print_progress("Start Inpainting Inference with ControlNet.")
571
+ else: print_progress("Start I2I Inference with ControlNet.")
572
+ pipe_i2i.enable_model_cpu_offload()
573
+ final_image = pipe_i2i(
574
+ prompt=prompt_mash,
575
+ control_image=images,
576
+ control_mode=modes,
577
+ image=image_input,
578
+ num_inference_steps=steps,
579
+ guidance_scale=cfg_scale,
580
+ #width=width,
581
+ #height=height,
582
+ controlnet_conditioning_scale=scales,
583
+ generator=generator,
584
+ joint_attention_kwargs={"scale": 1.0},
585
+ output_type="pil",
586
+ **kwargs,
587
+ ).images[0]
588
+ return final_image
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
589
  except Exception as e:
590
  print(e)
591
  raise gr.Error(f"I2I Inference Error: {e}") from e
592
 
593
+ def run_lora(prompt: str, image_input: dict, image_strength: float, task_type: str, turbo_mode: str, blur_mask: bool, blur_factor: float,
594
+ cfg_scale: float, steps: int, selected_indices, lora_scale_1: float, lora_scale_2: float,
595
+ randomize_seed: bool, seed: int, width: int, height: int, sigmas_factor: float, loras_state,
596
+ lora_json, cn_on: bool, translate_on: bool, progress=gr.Progress(track_tqdm=True)):
597
+ global pipe, pipe_i2i
598
  if not selected_indices and not is_valid_lora(lora_json):
599
  gr.Info("LoRA isn't selected.")
600
  # raise gr.Error("You must select a LoRA before proceeding.")
 
602
 
603
  selected_loras = [loras_state[idx] for idx in selected_indices]
604
 
605
+ if task_type in set(TASK_TYPE_I2I): is_i2i = True
606
+ else: is_i2i = False
 
 
 
 
 
 
 
 
607
  if translate_on: prompt = translate_to_en(prompt)
608
 
609
  # Build the prompt with trigger words
 
625
 
626
  print(pipe.get_active_adapters()) #
627
  print(pipe_i2i.get_active_adapters()) #
 
628
 
629
  clear_cache() #
630
 
 
632
  prompt_mash = prompt_mash + get_model_trigger(last_model)
633
  lora_names = []
634
  lora_weights = []
635
+ # Load Turbo LoRA weights
636
+ if turbo_mode != "None":
637
+ if is_i2i: pipe_i2i, lora_names, lora_weights, steps = turbo_loras(pipe_i2i, turbo_mode, lora_names, lora_weights)
638
+ else: pipe, lora_names, lora_weights, steps = turbo_loras(pipe, turbo_mode, lora_names, lora_weights)
639
+
640
+ # Load External LoRA weights
641
+ if is_valid_lora(lora_json):
642
  with calculateDuration("Loading External LoRA weights"):
643
+ if is_i2i: pipe_i2i, lora_names, lora_weights = fuse_loras(pipe_i2i, lora_json, lora_names, lora_weights)
644
+ else: pipe, lora_names, lora_weights = fuse_loras(pipe, lora_json, lora_names, lora_weights)
 
 
 
645
  trigger_word = get_trigger_word(lora_json)
646
  prompt_mash = f"{prompt_mash} {trigger_word}"
647
  print("Prompt Mash: ", prompt_mash) #
 
657
  lora_path = lora['repo']
658
  weight_name = lora.get("weights")
659
  print(f"Lora Path: {lora_path}")
660
+ if is_i2i:
 
 
 
 
 
 
 
 
661
  pipe_i2i.load_lora_weights(
662
  lora_path,
663
  weight_name=weight_name if weight_name else None,
 
675
  )
676
  print("Loaded LoRAs:", lora_names)
677
  if selected_indices or is_valid_lora(lora_json):
678
+ if is_i2i: pipe_i2i.set_adapters(lora_names, adapter_weights=lora_weights)
679
+ else: pipe.set_adapters(lora_names, adapter_weights=lora_weights)
 
 
 
 
680
 
681
  print(pipe.get_active_adapters()) #
682
  print(pipe_i2i.get_active_adapters()) #
 
683
 
684
  # Set random seed for reproducibility
685
  with calculateDuration("Randomizing seed"):
 
689
  # Generate image
690
  progress(0, desc="Running Inference.")
691
  if is_i2i:
692
+ final_image = generate_image_to_image(prompt_mash, image_input, image_strength, task_type, blur_mask, blur_factor,
693
  steps, cfg_scale, width, height, sigmas_factor, seed, cn_on)
694
  yield save_image(final_image, None, last_model, prompt_mash, height, width, steps, cfg_scale, seed), seed, gr.update(visible=False)
695
  else:
 
861
  show_share_button=False, show_download_button=True)
862
  history_clear_button = gr.Button(value="Clear History", variant="secondary")
863
  history_clear_button.click(lambda: ([], []), None, [history_gallery, history_files], queue=False, show_api=False)
 
864
  with gr.Row():
865
  with gr.Accordion("Advanced Settings", open=True):
866
  with gr.Tab("Generation Settings"):
 
868
  with gr.Group():
869
  with gr.Row():
870
  model_name = gr.Dropdown(label="Base Model", info="You can enter a huggingface model repo_id or path of single safetensors file to want to use.",
871
+ choices=models, value=models[0], allow_custom_value=True, min_width=320, scale=5)
872
  model_type = gr.Radio(label="Model type", info="Model type of single safetensors file",
873
+ choices=list(single_file_base_models.keys()), value=list(single_file_base_models.keys())[0], scale=1)
874
  model_info = gr.Markdown(elem_classes="info")
875
  with gr.Row():
876
  width = gr.Slider(label="Width", minimum=256, maximum=1536, step=64, value=1024)
 
880
  with gr.Row():
881
  randomize_seed = gr.Checkbox(True, label="Randomize seed")
882
  seed = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=0, randomize=True)
883
+ with gr.Row():
884
+ turbo_mode = gr.Radio(label="Turbo mode", choices=["None", "Hyper-FLUX.1-dev-8steps", "Hyper-FLUX.1-dev-16steps", "FLUX.1-Turbo-Alpha 8-steps"], value="None")
885
  sigmas_factor = gr.Slider(label="Sigmas factor", minimum=0.01, maximum=1.00, step=0.01, value=0.95)
886
+ data_type = gr.Radio(label="Data type", choices=["BF16"], value="BF16", visible=False)
887
  disable_model_cache = gr.Checkbox(False, label="Disable model caching")
888
  with gr.Tab("Image-to-Image"):
889
  with gr.Row():
890
  with gr.Column():
891
  #input_image = gr.Image(label="Input image", type="filepath", height=256, sources=["upload", "clipboard"], show_share_button=False)
892
  input_image = gr.ImageEditor(label='Input image', type='filepath', sources=["upload", "clipboard"], image_mode='RGB', show_share_button=False, show_fullscreen_button=False,
893
+ layers=False, brush=gr.Brush(colors=["white"], color_mode="fixed", default_size=32), eraser=gr.Eraser(default_size="32"), value=None,
894
+ canvas_size=(384, 384), width=384, height=512)
895
  with gr.Column():
896
+
897
+ task_type = gr.Radio(label="Task", choices=TASK_TYPE_T2I+TASK_TYPE_I2I, value=TASK_TYPE_T2I[0])
898
  image_strength = gr.Slider(label="Strength", info="Lower means more image influence in I2I, opposite in Inpaint", minimum=0.01, maximum=1.0, step=0.01, value=0.75)
899
  blur_mask = gr.Checkbox(label="Blur mask", value=False)
900
  blur_factor = gr.Slider(label="Blur factor", minimum=0, maximum=50, step=1, value=33)
 
999
  gr.on(
1000
  triggers=[generate_button.click, prompt.submit],
1001
  fn=change_base_model,
1002
+ inputs=[model_name, cn_on, disable_model_cache, model_type, task_type, data_type],
1003
  outputs=[result],
1004
  queue=True,
1005
  show_api=False,
1006
  trigger_mode="once",
1007
  ).success(
1008
  fn=run_lora,
1009
+ inputs=[prompt, input_image, image_strength, task_type, turbo_mode, blur_mask, blur_factor, cfg_scale, steps, selected_indices, lora_scale_1, lora_scale_2,
1010
  randomize_seed, seed, width, height, sigmas_factor, loras_state, lora_repo_json, cn_on, auto_trans],
1011
  outputs=[result, seed, progress_bar],
1012
  queue=True,
1013
  show_api=True,
 
 
 
 
1014
  ).success(save_image_history, [result, history_gallery, history_files, model_name], [history_gallery, history_files], queue=False, show_api=False)
1015
 
1016
  input_image.clear(lambda: gr.update(value="Text-to-Image"), None, [task_type], queue=False, show_api=False)
1017
+ input_image.upload(preprocess_i2i_image, [input_image, input_image_preprocess, height, width], [input_image], queue=False, show_api=False)#\
1018
+ #.success(lambda: gr.update(value="Image-to-Image"), None, [task_type], queue=False, show_api=False)
1019
  gr.on(
1020
  triggers=[model_name.change, cn_on.change],
1021
  fn=get_t2i_model_info,
 
1024
  queue=False,
1025
  show_api=False,
1026
  trigger_mode="once",
1027
+ )
1028
  prompt_enhance.click(enhance_prompt, [prompt], [prompt], queue=False, show_api=False)
1029
 
1030
  gr.on(
env.py CHANGED
@@ -10,9 +10,8 @@ num_loras = 3
10
  num_cns = 2
11
 
12
 
13
- models = [
14
  "camenduru/FLUX.1-dev-diffusers",
15
- "black-forest-labs/FLUX.1-schnell",
16
  "sayakpaul/FLUX.1-merged",
17
  "ostris/OpenFLUX.1",
18
  "multimodalart/FLUX.1-dev2pro-full",
@@ -63,11 +62,27 @@ models = [
63
  "John6666/xe-asian-flux-01-fp8-flux",
64
  "John6666/fluxescore-dev-v10fp16-fp8-flux",
65
  "John6666/2758-flux-asian-utopian-v30fp8noclip-fp8-flux",
 
66
  "https://huggingface.co/StableDiffusionVN/SDVN11-Ghibli-Flux/blob/main/SDVN11-Ghibli-Flux_fp8-hyper.safetensors",
67
  "https://huggingface.co/datasets/John6666/flux1-backup-202410/blob/main/iniverseMixXLSFWNSFW_f1dFP16V10.safetensors",
 
68
  # "",
69
  ]
70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  model_trigger = {
72
  "Raelina/Raemu-Flux": "anime",
73
  "John6666/raemu-flux-v10-fp8-flux": "anime",
@@ -77,6 +92,7 @@ model_trigger = {
77
  single_file_base_models = {
78
  "dev": "camenduru/FLUX.1-dev-diffusers",
79
  "schnell": "black-forest-labs/FLUX.1-schnell",
 
80
  }
81
 
82
  # List all Models for specified user
 
10
  num_cns = 2
11
 
12
 
13
+ models_dev = [
14
  "camenduru/FLUX.1-dev-diffusers",
 
15
  "sayakpaul/FLUX.1-merged",
16
  "ostris/OpenFLUX.1",
17
  "multimodalart/FLUX.1-dev2pro-full",
 
62
  "John6666/xe-asian-flux-01-fp8-flux",
63
  "John6666/fluxescore-dev-v10fp16-fp8-flux",
64
  "John6666/2758-flux-asian-utopian-v30fp8noclip-fp8-flux",
65
+ "trongg/FLUX_dev2pro_nsfw_context_lora",
66
  "https://huggingface.co/StableDiffusionVN/SDVN11-Ghibli-Flux/blob/main/SDVN11-Ghibli-Flux_fp8-hyper.safetensors",
67
  "https://huggingface.co/datasets/John6666/flux1-backup-202410/blob/main/iniverseMixXLSFWNSFW_f1dFP16V10.safetensors",
68
+ "https://huggingface.co/city96/FLUX.1-dev-gguf/blob/main/flux1-dev-Q2_K.gguf",
69
  # "",
70
  ]
71
 
72
+ models_schnell = [
73
+ "black-forest-labs/FLUX.1-schnell",
74
+ ]
75
+
76
+ models_fill = ["fuliucansheng/FLUX.1-Fill-dev-diffusers"]
77
+
78
+ models_dedistill = []
79
+
80
+ models_canny = ["sayakpaul/FLUX.1-Canny-dev-nf4"]
81
+
82
+ models_depth = ["sayakpaul/FLUX.1-Depth-dev-nf4"]
83
+
84
+ models = models_dev + models_schnell + models_fill
85
+
86
  model_trigger = {
87
  "Raelina/Raemu-Flux": "anime",
88
  "John6666/raemu-flux-v10-fp8-flux": "anime",
 
92
  single_file_base_models = {
93
  "dev": "camenduru/FLUX.1-dev-diffusers",
94
  "schnell": "black-forest-labs/FLUX.1-schnell",
95
+ "fill": "fuliucansheng/FLUX.1-Fill-dev-diffusers",
96
  }
97
 
98
  # List all Models for specified user
mod.py CHANGED
@@ -8,7 +8,7 @@ import subprocess
8
  import os
9
  import re
10
  from translatepy import Translator
11
- from huggingface_hub import HfApi
12
  from env import num_cns, model_trigger, HF_TOKEN, CIVITAI_API_KEY, DOWNLOAD_LORA_LIST, DIRECTORY_LORAS
13
  from modutils import download_things
14
 
@@ -232,6 +232,14 @@ def set_control_union_image(i: int, mode: str, image: Image.Image | None, height
232
  return control_images[i]
233
 
234
 
 
 
 
 
 
 
 
 
235
  def preprocess_i2i_image(image_path_dict: dict, is_preprocess: bool, height: int, width: int):
236
  try:
237
  if not is_preprocess: return gr.update()
@@ -275,24 +283,22 @@ def get_model_trigger(model_name: str):
275
 
276
  # https://huggingface.co/docs/diffusers/v0.23.1/en/api/loaders#diffusers.loaders.LoraLoaderMixin.fuse_lora
277
  # https://github.com/huggingface/diffusers/issues/4919
278
- def fuse_loras(pipe, lorajson: list[dict]):
279
  try:
280
- if not lorajson or not isinstance(lorajson, list): return pipe, [], []
281
- a_list = []
282
- w_list = []
283
  for d in lorajson:
284
  if not d or not isinstance(d, dict) or not d["name"] or d["name"] == "None": continue
285
  k = d["name"]
286
  if is_repo_name(k) and is_repo_exists(k):
287
  a_name = Path(k).stem
288
- pipe.load_lora_weights(k, weight_name=d["filename"], adapter_name = a_name, low_cpu_mem_usage=True)
289
  elif not Path(k).exists():
290
  print(f"LoRA not found: {k}")
291
  continue
292
  else:
293
  w_name = Path(k).name
294
  a_name = Path(k).stem
295
- pipe.load_lora_weights(k, weight_name = w_name, adapter_name = a_name, low_cpu_mem_usage=True)
296
  a_list.append(a_name)
297
  w_list.append(d["scale"])
298
  if not a_list: return pipe, [], []
@@ -305,6 +311,25 @@ def fuse_loras(pipe, lorajson: list[dict]):
305
  raise Exception(f"External LoRA Error: {e}") from e
306
 
307
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
  def description_ui():
309
  gr.Markdown(
310
  """
 
8
  import os
9
  import re
10
  from translatepy import Translator
11
+ from huggingface_hub import HfApi, hf_hub_download
12
  from env import num_cns, model_trigger, HF_TOKEN, CIVITAI_API_KEY, DOWNLOAD_LORA_LIST, DIRECTORY_LORAS
13
  from modutils import download_things
14
 
 
232
  return control_images[i]
233
 
234
 
235
+ def get_canny_image(image: Image.Image, height: int, width: int):
236
+ return preprocess_image(image, "canny", height, width, 384)
237
+
238
+
239
+ def get_depth_image(image: Image.Image, height: int, width: int):
240
+ return preprocess_image(image, "depth_midas", height, width, 384)
241
+
242
+
243
  def preprocess_i2i_image(image_path_dict: dict, is_preprocess: bool, height: int, width: int):
244
  try:
245
  if not is_preprocess: return gr.update()
 
283
 
284
  # https://huggingface.co/docs/diffusers/v0.23.1/en/api/loaders#diffusers.loaders.LoraLoaderMixin.fuse_lora
285
  # https://github.com/huggingface/diffusers/issues/4919
286
+ def fuse_loras(pipe, lorajson: list[dict], a_list: list, w_list: list):
287
  try:
288
+ if not lorajson or not isinstance(lorajson, list): return pipe, a_list, w_list
 
 
289
  for d in lorajson:
290
  if not d or not isinstance(d, dict) or not d["name"] or d["name"] == "None": continue
291
  k = d["name"]
292
  if is_repo_name(k) and is_repo_exists(k):
293
  a_name = Path(k).stem
294
+ pipe.load_lora_weights(k, weight_name=d["filename"], adapter_name = a_name, low_cpu_mem_usage=False)
295
  elif not Path(k).exists():
296
  print(f"LoRA not found: {k}")
297
  continue
298
  else:
299
  w_name = Path(k).name
300
  a_name = Path(k).stem
301
+ pipe.load_lora_weights(k, weight_name = w_name, adapter_name = a_name, low_cpu_mem_usage=False)
302
  a_list.append(a_name)
303
  w_list.append(d["scale"])
304
  if not a_list: return pipe, [], []
 
311
  raise Exception(f"External LoRA Error: {e}") from e
312
 
313
 
314
+ def turbo_loras(pipe, turbo_mode: str, lora_names: list, lora_weights: list):
315
+ if turbo_mode == "Hyper-FLUX.1-dev-8steps":
316
+ lora_names.append("Hyper-FLUX1-dev-8steps")
317
+ lora_weights.append(0.125)
318
+ pipe.load_lora_weights(hf_hub_download("ByteDance/Hyper-SD", "Hyper-FLUX.1-dev-8steps-lora.safetensors"), adapter_name=lora_names[-1], low_cpu_mem_usage=False)
319
+ steps = 8
320
+ elif turbo_mode == "Hyper-FLUX.1-dev-16steps":
321
+ lora_names.append("Hyper-FLUX1-dev-16steps")
322
+ lora_weights.append(0.125)
323
+ pipe.load_lora_weights(hf_hub_download("ByteDance/Hyper-SD", "Hyper-FLUX.1-dev-16steps-lora.safetensors"), adapter_name=lora_names[-1], low_cpu_mem_usage=False)
324
+ steps = 16
325
+ elif turbo_mode == "FLUX.1-Turbo-Alpha 8-steps":
326
+ lora_names.append("FLUX1-Turbo-Alpha 8-steps")
327
+ lora_weights.append(1.0)
328
+ pipe.load_lora_weights("alimama-creative/FLUX.1-Turbo-Alpha", adapter_name=lora_names[-1], low_cpu_mem_usage=False)
329
+ steps = 8
330
+ return pipe, lora_names, lora_weights, steps
331
+
332
+
333
  def description_ui():
334
  gr.Markdown(
335
  """
requirements.txt CHANGED
@@ -16,4 +16,7 @@ deepspeed
16
  mediapipe
17
  openai>=1.37.0
18
  translatepy
19
- unidecode
 
 
 
 
16
  mediapipe
17
  openai>=1.37.0
18
  translatepy
19
+ unidecode
20
+ optimum-quanto
21
+ bitsandbytes
22
+ gguf