multimodalart HF staff commited on
Commit
c724573
1 Parent(s): 463aefd

Add live previews (now for realz) (#18)

Browse files

- Add live previews (now for realz) (2ed4418f4c92b7cc2acc65a4b655a3a0c28eadd4)
- Update app.py (aaff7099c16d675defc700eb3004d4015af257a0)
- Update loras.json (0a8b917725e831072aefd745f37bcea1888d4a84)

Files changed (3) hide show
  1. app.py +28 -12
  2. live_preview_helpers.py +6 -5
  3. loras.json +37 -4
app.py CHANGED
@@ -5,7 +5,9 @@ import logging
5
  import torch
6
  from PIL import Image
7
  import spaces
8
- from diffusers import DiffusionPipeline
 
 
9
  from huggingface_hub import hf_hub_download, HfFileSystem, ModelCard, snapshot_download
10
  import copy
11
  import random
@@ -16,11 +18,18 @@ with open('loras.json', 'r') as f:
16
  loras = json.load(f)
17
 
18
  # Initialize the base model
 
 
19
  base_model = "black-forest-labs/FLUX.1-dev"
20
- pipe = DiffusionPipeline.from_pretrained(base_model, torch_dtype=torch.bfloat16)
 
 
 
21
 
22
  MAX_SEED = 2**32-1
23
 
 
 
24
  class calculateDuration:
25
  def __init__(self, activity_name=""):
26
  self.activity_name = activity_name
@@ -61,10 +70,9 @@ def update_selection(evt: gr.SelectData, width, height):
61
  def generate_image(prompt_mash, steps, seed, cfg_scale, width, height, lora_scale, progress):
62
  pipe.to("cuda")
63
  generator = torch.Generator(device="cuda").manual_seed(seed)
64
-
65
  with calculateDuration("Generating image"):
66
  # Generate image
67
- image = pipe(
68
  prompt=prompt_mash,
69
  num_inference_steps=steps,
70
  guidance_scale=cfg_scale,
@@ -72,13 +80,14 @@ def generate_image(prompt_mash, steps, seed, cfg_scale, width, height, lora_scal
72
  height=height,
73
  generator=generator,
74
  joint_attention_kwargs={"scale": lora_scale},
75
- ).images[0]
76
- return image
 
 
77
 
78
  def run_lora(prompt, cfg_scale, steps, selected_index, randomize_seed, seed, width, height, lora_scale, progress=gr.Progress(track_tqdm=True)):
79
  if selected_index is None:
80
  raise gr.Error("You must select a LoRA before proceeding.")
81
-
82
  selected_lora = loras[selected_index]
83
  lora_path = selected_lora["repo"]
84
  trigger_word = selected_lora["trigger_word"]
@@ -92,24 +101,31 @@ def run_lora(prompt, cfg_scale, steps, selected_index, randomize_seed, seed, wid
92
  prompt_mash = f"{trigger_word} {prompt}"
93
  else:
94
  prompt_mash = prompt
 
95
  # Load LoRA weights
96
  with calculateDuration(f"Loading LoRA weights for {selected_lora['title']}"):
97
  if "weights" in selected_lora:
98
  pipe.load_lora_weights(lora_path, weight_name=selected_lora["weights"])
99
- #pipe.fuse_lora()
100
  else:
101
  pipe.load_lora_weights(lora_path)
102
- #pipe.fuse_lora()
103
  # Set random seed for reproducibility
104
  with calculateDuration("Randomizing seed"):
105
  if randomize_seed:
106
  seed = random.randint(0, MAX_SEED)
 
 
107
 
108
- image = generate_image(prompt_mash, steps, seed, cfg_scale, width, height, lora_scale, progress)
 
 
 
 
 
109
  pipe.to("cpu")
110
- #pipe.unfuse_lora()
111
  pipe.unload_lora_weights()
112
- return image, seed
 
113
 
114
  def get_huggingface_safetensors(link):
115
  split_link = link.split("/")
 
5
  import torch
6
  from PIL import Image
7
  import spaces
8
+ from diffusers import DiffusionPipeline, AutoencoderTiny, AutoencoderKL
9
+ from live_preview_helpers import calculate_shift, retrieve_timesteps, flux_pipe_call_that_returns_an_iterable_of_images
10
+
11
  from huggingface_hub import hf_hub_download, HfFileSystem, ModelCard, snapshot_download
12
  import copy
13
  import random
 
18
  loras = json.load(f)
19
 
20
  # Initialize the base model
21
+ dtype = torch.bfloat16
22
+ device = "cuda" if torch.cuda.is_available() else "cpu"
23
  base_model = "black-forest-labs/FLUX.1-dev"
24
+
25
+ taef1 = AutoencoderTiny.from_pretrained("madebyollin/taef1", torch_dtype=dtype).to(device)
26
+ good_vae = AutoencoderKL.from_pretrained(base_model, subfolder="vae", torch_dtype=dtype).to(device)
27
+ pipe = DiffusionPipeline.from_pretrained(base_model, torch_dtype=dtype, vae=taef1).to(device)
28
 
29
  MAX_SEED = 2**32-1
30
 
31
+ pipe.flux_pipe_call_that_returns_an_iterable_of_images = flux_pipe_call_that_returns_an_iterable_of_images.__get__(pipe)
32
+
33
  class calculateDuration:
34
  def __init__(self, activity_name=""):
35
  self.activity_name = activity_name
 
70
  def generate_image(prompt_mash, steps, seed, cfg_scale, width, height, lora_scale, progress):
71
  pipe.to("cuda")
72
  generator = torch.Generator(device="cuda").manual_seed(seed)
 
73
  with calculateDuration("Generating image"):
74
  # Generate image
75
+ for img in pipe.flux_pipe_call_that_returns_an_iterable_of_images(
76
  prompt=prompt_mash,
77
  num_inference_steps=steps,
78
  guidance_scale=cfg_scale,
 
80
  height=height,
81
  generator=generator,
82
  joint_attention_kwargs={"scale": lora_scale},
83
+ output_type="pil",
84
+ good_vae=good_vae,
85
+ ):
86
+ yield img
87
 
88
  def run_lora(prompt, cfg_scale, steps, selected_index, randomize_seed, seed, width, height, lora_scale, progress=gr.Progress(track_tqdm=True)):
89
  if selected_index is None:
90
  raise gr.Error("You must select a LoRA before proceeding.")
 
91
  selected_lora = loras[selected_index]
92
  lora_path = selected_lora["repo"]
93
  trigger_word = selected_lora["trigger_word"]
 
101
  prompt_mash = f"{trigger_word} {prompt}"
102
  else:
103
  prompt_mash = prompt
104
+
105
  # Load LoRA weights
106
  with calculateDuration(f"Loading LoRA weights for {selected_lora['title']}"):
107
  if "weights" in selected_lora:
108
  pipe.load_lora_weights(lora_path, weight_name=selected_lora["weights"])
 
109
  else:
110
  pipe.load_lora_weights(lora_path)
111
+
112
  # Set random seed for reproducibility
113
  with calculateDuration("Randomizing seed"):
114
  if randomize_seed:
115
  seed = random.randint(0, MAX_SEED)
116
+
117
+ image_generator = generate_image(prompt_mash, steps, seed, cfg_scale, width, height, lora_scale, progress)
118
 
119
+ # Consume the generator to get the final image
120
+ final_image = None
121
+ for image in image_generator:
122
+ final_image = image
123
+ yield image, seed # Yield intermediate images and seed
124
+
125
  pipe.to("cpu")
 
126
  pipe.unload_lora_weights()
127
+
128
+ return final_image, seed # Return the final image and seed
129
 
130
  def get_huggingface_safetensors(link):
131
  split_link = link.split("/")
live_preview_helpers.py CHANGED
@@ -59,6 +59,7 @@ def flux_pipe_call_that_returns_an_iterable_of_images(
59
  return_dict: bool = True,
60
  joint_attention_kwargs: Optional[Dict[str, Any]] = None,
61
  max_sequence_length: int = 512,
 
62
  ):
63
  height = height or self.default_sample_size * self.vae_scale_factor
64
  width = width or self.default_sample_size * self.vae_scale_factor
@@ -156,10 +157,10 @@ def flux_pipe_call_that_returns_an_iterable_of_images(
156
  yield self.image_processor.postprocess(image, output_type=output_type)[0]
157
  torch.cuda.empty_cache()
158
 
159
- # Final image
160
- latents = self._unpack_latents(latents, height, width, self.vae_scale_factor)
161
- latents = (latents / self.vae.config.scaling_factor) + self.vae.config.shift_factor
162
- image = self.vae.decode(latents, return_dict=False)[0]
163
  self.maybe_free_model_hooks()
164
  torch.cuda.empty_cache()
165
- return self.image_processor.postprocess(image, output_type=output_type)[0], 0
 
59
  return_dict: bool = True,
60
  joint_attention_kwargs: Optional[Dict[str, Any]] = None,
61
  max_sequence_length: int = 512,
62
+ good_vae: Optional[Any] = None,
63
  ):
64
  height = height or self.default_sample_size * self.vae_scale_factor
65
  width = width or self.default_sample_size * self.vae_scale_factor
 
157
  yield self.image_processor.postprocess(image, output_type=output_type)[0]
158
  torch.cuda.empty_cache()
159
 
160
+ # Final image using good_vae
161
+ latents = self._unpack_latents(latents, height, width, good_vae.config.vae_scale_factor)
162
+ latents = (latents / good_vae.config.scaling_factor) + good_vae.config.shift_factor
163
+ image = good_vae.decode(latents, return_dict=False)[0]
164
  self.maybe_free_model_hooks()
165
  torch.cuda.empty_cache()
166
+ yield self.image_processor.postprocess(image, output_type=output_type)[0]
loras.json CHANGED
@@ -7,10 +7,10 @@
7
  "aspect": "portrait"
8
  },
9
  {
10
- "image": "https://huggingface.co/alvdansen/frosting_lane_flux/resolve/main/images/content%20-%202024-08-11T005936.346.jpeg",
11
- "title": "Frosting Lane Flux",
12
- "repo": "alvdansen/frosting_lane_flux",
13
- "trigger_word": ""
14
  },
15
  {
16
  "image": "https://huggingface.co/AIWarper/RubberCore1920sCartoonStyle/resolve/main/images/Rub_00006_.png",
@@ -19,12 +19,32 @@
19
  "trigger_word": "RU883R style",
20
  "trigger_position": "prepend"
21
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  {
23
  "image": "https://github.com/XLabs-AI/x-flux/blob/main/assets/readme/examples/picture-6-rev1.png?raw=true",
24
  "title": "flux-Realism",
25
  "repo": "XLabs-AI/flux-RealismLora",
26
  "trigger_word": ""
27
  },
 
 
 
 
 
 
 
28
  {
29
  "image": "https://huggingface.co/nerijs/animation2k-flux/resolve/main/images/Q8-oVxNnXvZ9HNrgbNpGw_02762aaaba3b47859ee5fe9403a371e3.png",
30
  "title": "animation2k",
@@ -49,6 +69,12 @@
49
  "repo": "alvdansen/flux-koda",
50
  "trigger_word": "flmft style"
51
  },
 
 
 
 
 
 
52
  {
53
  "image": "https://pbs.twimg.com/media/GU7NsZPa8AA4Ddl?format=jpg&name=4096x4096",
54
  "title": "Half Illustration",
@@ -92,6 +118,13 @@
92
  "weights": "anime_lora.safetensors",
93
  "trigger_word": ", anime"
94
  },
 
 
 
 
 
 
 
95
  {
96
  "image": "https://huggingface.co/kudzueye/Boreal/resolve/main/images/ComfyUI_00845_.png",
97
  "title": "Boreal",
 
7
  "aspect": "portrait"
8
  },
9
  {
10
+ "image": "https://huggingface.co/alvdansen/softpasty-flux-dev/resolve/main/images/ComfyUI_00814_%20(2).png",
11
+ "title": "SoftPasty",
12
+ "repo": "alvdansen/softpasty-flux-dev",
13
+ "trigger_word": "araminta_illus illustration style"
14
  },
15
  {
16
  "image": "https://huggingface.co/AIWarper/RubberCore1920sCartoonStyle/resolve/main/images/Rub_00006_.png",
 
19
  "trigger_word": "RU883R style",
20
  "trigger_position": "prepend"
21
  },
22
+ {
23
+ "image": "https://huggingface.co/mgwr/Cine-Aesthetic/resolve/main/images/00030-1333633802.png",
24
+ "title": "Cine Aesthetic",
25
+ "repo": "mgwr/Cine-Aesthetic",
26
+ "trigger_word": "mgwr/cine",
27
+ "trigger_position": "prepend"
28
+ },
29
+ {
30
+ "image": "https://huggingface.co/Shakker-Labs/FLUX.1-dev-LoRA-blended-realistic-illustration/resolve/main/images/example3.png",
31
+ "title": "Blended Realistic Illustration",
32
+ "repo": "Shakker-Labs/FLUX.1-dev-LoRA-blended-realistic-illustration",
33
+ "trigger_word": "artistic style blends reality and illustration elements"
34
+ },
35
  {
36
  "image": "https://github.com/XLabs-AI/x-flux/blob/main/assets/readme/examples/picture-6-rev1.png?raw=true",
37
  "title": "flux-Realism",
38
  "repo": "XLabs-AI/flux-RealismLora",
39
  "trigger_word": ""
40
  },
41
+ {
42
+ "image": "https://huggingface.co/multimodalart/vintage-ads-flux/resolve/main/samples/j_XNU6Oe0mgttyvf9uPb3_dc244dd3d6c246b4aff8351444868d66.png",
43
+ "title": "Vintage Ads",
44
+ "repo":"multimodalart/vintage-ads-flux",
45
+ "trigger_word": "a vintage ad of",
46
+ "trigger_position": "prepend"
47
+ },
48
  {
49
  "image": "https://huggingface.co/nerijs/animation2k-flux/resolve/main/images/Q8-oVxNnXvZ9HNrgbNpGw_02762aaaba3b47859ee5fe9403a371e3.png",
50
  "title": "animation2k",
 
69
  "repo": "alvdansen/flux-koda",
70
  "trigger_word": "flmft style"
71
  },
72
+ {
73
+ "image": "https://huggingface.co/alvdansen/frosting_lane_flux/resolve/main/images/content%20-%202024-08-11T005936.346.jpeg",
74
+ "title": "Frosting Lane Flux",
75
+ "repo": "alvdansen/frosting_lane_flux",
76
+ "trigger_word": ""
77
+ },
78
  {
79
  "image": "https://pbs.twimg.com/media/GU7NsZPa8AA4Ddl?format=jpg&name=4096x4096",
80
  "title": "Half Illustration",
 
118
  "weights": "anime_lora.safetensors",
119
  "trigger_word": ", anime"
120
  },
121
+ {
122
+ "image": "https://github.com/XLabs-AI/x-flux/blob/main/assets/readme/examples/result_14.png?raw=true",
123
+ "title": "80s Cyberpunk",
124
+ "repo": "fofr/flux-80s-cyberpunk",
125
+ "trigger_word": "style of 80s cyberpunk",
126
+ "aspect": "portrait"
127
+ },
128
  {
129
  "image": "https://huggingface.co/kudzueye/Boreal/resolve/main/images/ComfyUI_00845_.png",
130
  "title": "Boreal",