rupeshs commited on
Commit
415da73
1 Parent(s): 1f0e151

updated with latest changes

Browse files
app.py CHANGED
@@ -1,11 +1,14 @@
1
  from app_settings import AppSettings
2
  from utils import show_system_info
 
 
3
  import constants
4
  from argparse import ArgumentParser
5
- from context import Context
6
  from constants import APP_VERSION, LCM_DEFAULT_MODEL_OPENVINO
7
  from models.interface_types import InterfaceType
8
  from constants import DEVICE
 
9
 
10
  parser = ArgumentParser(description=f"FAST SD CPU {constants.APP_VERSION}")
11
  parser.add_argument(
@@ -128,10 +131,23 @@ parser.add_argument(
128
  help="Interactive CLI mode",
129
  )
130
  parser.add_argument(
 
131
  "--use_tiny_auto_encoder",
132
  action="store_true",
133
  help="Use tiny auto encoder for SD (TAESD)",
134
  )
 
 
 
 
 
 
 
 
 
 
 
 
135
  args = parser.parse_args()
136
 
137
  if args.version:
@@ -141,8 +157,12 @@ if args.version:
141
  # parser.print_help()
142
  show_system_info()
143
  print(f"Using device : {constants.DEVICE}")
144
- app_settings = AppSettings()
145
- app_settings.load()
 
 
 
 
146
  print(
147
  f"Found {len(app_settings.stable_diffsuion_models)} stable diffusion models in config/stable-diffusion-models.txt"
148
  )
@@ -152,8 +172,76 @@ print(
152
  print(
153
  f"Found {len(app_settings.openvino_lcm_models)} OpenVINO LCM models in config/openvino-lcm-models.txt"
154
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
 
156
- from frontend.webui.hf_demo import start_demo_text_to_image
 
 
 
 
 
 
 
 
 
157
 
158
- print("Starting demo text to image")
159
- start_demo_text_to_image(False)
 
 
 
 
1
  from app_settings import AppSettings
2
  from utils import show_system_info
3
+ from PIL import Image
4
+ from backend.models.lcmdiffusion_setting import DiffusionTask
5
  import constants
6
  from argparse import ArgumentParser
7
+
8
  from constants import APP_VERSION, LCM_DEFAULT_MODEL_OPENVINO
9
  from models.interface_types import InterfaceType
10
  from constants import DEVICE
11
+ from state import get_settings, get_context
12
 
13
  parser = ArgumentParser(description=f"FAST SD CPU {constants.APP_VERSION}")
14
  parser.add_argument(
 
131
  help="Interactive CLI mode",
132
  )
133
  parser.add_argument(
134
+ "-t",
135
  "--use_tiny_auto_encoder",
136
  action="store_true",
137
  help="Use tiny auto encoder for SD (TAESD)",
138
  )
139
+ parser.add_argument(
140
+ "-f",
141
+ "--file",
142
+ type=str,
143
+ help="Input image for img2img mode",
144
+ default="",
145
+ )
146
+ parser.add_argument(
147
+ "--img2img",
148
+ action="store_true",
149
+ help="img2img mode; requires input file via -f argument",
150
+ )
151
  args = parser.parse_args()
152
 
153
  if args.version:
 
157
  # parser.print_help()
158
  show_system_info()
159
  print(f"Using device : {constants.DEVICE}")
160
+ if args.webui:
161
+ app_settings = get_settings()
162
+ else:
163
+ app_settings = get_settings()
164
+
165
+ print(f"Found {len(app_settings.lcm_models)} LCM models in config/lcm-models.txt")
166
  print(
167
  f"Found {len(app_settings.stable_diffsuion_models)} stable diffusion models in config/stable-diffusion-models.txt"
168
  )
 
172
  print(
173
  f"Found {len(app_settings.openvino_lcm_models)} OpenVINO LCM models in config/openvino-lcm-models.txt"
174
  )
175
+ if args.gui:
176
+ from frontend.gui.ui import start_gui
177
+
178
+ print("Starting desktop GUI mode(Qt)")
179
+ start_gui(
180
+ [],
181
+ app_settings,
182
+ )
183
+ elif args.webui:
184
+ from frontend.webui.ui import start_webui
185
+
186
+ print("Starting web UI mode")
187
+ start_webui(
188
+ args.share,
189
+ )
190
+ elif args.realtime:
191
+ from frontend.webui.realtime_ui import start_realtime_text_to_image
192
+
193
+ print("Starting realtime text to image(EXPERIMENTAL)")
194
+ start_realtime_text_to_image(args.share)
195
+ else:
196
+ context = get_context(InterfaceType.CLI)
197
+ config = app_settings.settings
198
+
199
+ if args.use_openvino:
200
+ config.lcm_diffusion_setting.lcm_model_id = LCM_DEFAULT_MODEL_OPENVINO
201
+ else:
202
+ config.lcm_diffusion_setting.lcm_model_id = args.lcm_model_id
203
+
204
+ config.lcm_diffusion_setting.prompt = args.prompt
205
+ config.lcm_diffusion_setting.image_height = args.image_height
206
+ config.lcm_diffusion_setting.image_width = args.image_width
207
+ config.lcm_diffusion_setting.guidance_scale = args.guidance_scale
208
+ config.lcm_diffusion_setting.number_of_images = args.number_of_images
209
+ config.lcm_diffusion_setting.inference_steps = args.inference_steps
210
+ config.lcm_diffusion_setting.seed = args.seed
211
+ config.lcm_diffusion_setting.use_openvino = args.use_openvino
212
+ config.lcm_diffusion_setting.use_tiny_auto_encoder = args.use_tiny_auto_encoder
213
+ config.lcm_diffusion_setting.use_lcm_lora = args.use_lcm_lora
214
+ config.lcm_diffusion_setting.lcm_lora.base_model_id = args.base_model_id
215
+ config.lcm_diffusion_setting.lcm_lora.lcm_lora_id = args.lcm_lora_id
216
+ config.lcm_diffusion_setting.diffusion_task = DiffusionTask.text_to_image.value
217
+
218
+ if args.img2img and args.file != "" :
219
+ config.lcm_diffusion_setting.init_image = Image.open(args.file)
220
+ config.lcm_diffusion_setting.diffusion_task = DiffusionTask.image_to_image.value
221
+ elif args.img2img and args.file == "":
222
+ print("You need to specify a file in img2img mode")
223
+ exit()
224
+
225
+ if args.seed > -1:
226
+ config.lcm_diffusion_setting.use_seed = True
227
+ else:
228
+ config.lcm_diffusion_setting.use_seed = False
229
+ config.lcm_diffusion_setting.use_offline_model = args.use_offline_model
230
+ config.lcm_diffusion_setting.use_safety_checker = args.use_safety_checker
231
 
232
+ if args.interactive:
233
+ while True:
234
+ user_input = input(">>")
235
+ if user_input == "exit":
236
+ break
237
+ config.lcm_diffusion_setting.prompt = user_input
238
+ context.generate_text_to_image(
239
+ settings=config,
240
+ device=DEVICE,
241
+ )
242
 
243
+ else:
244
+ context.generate_text_to_image(
245
+ settings=config,
246
+ device=DEVICE,
247
+ )
app_settings.py CHANGED
@@ -3,15 +3,30 @@ from os import path, makedirs
3
  from models.settings import Settings
4
  from paths import FastStableDiffusionPaths
5
  from utils import get_models_from_text_file
6
- from constants import OPENVINO_LCM_MODELS_FILE, LCM_LORA_MODELS_FILE, SD_MODELS_FILE
 
 
 
 
 
 
7
 
8
 
9
  class AppSettings:
10
  def __init__(self):
11
  self.config_path = FastStableDiffusionPaths().get_app_settings_path()
12
- self._stable_diffsuion_models = ["Lykon/dreamshaper-7"]
13
- self._lcm_lora_models = ["latent-consistency/lcm-lora-sdv1-5"]
14
- self._openvino_lcm_models = ["rupeshs/LCM-dreamshaper-v7-openvino"]
 
 
 
 
 
 
 
 
 
15
 
16
  @property
17
  def settings(self):
@@ -25,36 +40,47 @@ class AppSettings:
25
  def openvino_lcm_models(self):
26
  return self._openvino_lcm_models
27
 
 
 
 
 
28
  @property
29
  def lcm_lora_models(self):
30
  return self._lcm_lora_models
31
 
32
- def load(self):
33
- if not path.exists(self.config_path):
34
- base_dir = path.dirname(self.config_path)
35
- if not path.exists(base_dir):
36
- makedirs(base_dir)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  try:
38
- print("Settings not found creating default settings")
39
- with open(self.config_path, "w") as file:
40
- yaml.dump(
41
- self._load_default(),
42
- file,
43
- )
44
  except Exception as ex:
45
- print(f"Error in creating settings : {ex}")
46
- exit()
47
- try:
48
- with open(self.config_path) as file:
49
- settings_dict = yaml.safe_load(file)
50
- self._config = Settings.parse_obj(settings_dict)
51
- except Exception as ex:
52
- print(f"Error in loading settings : {ex}")
53
 
54
  def save(self):
55
  try:
56
  with open(self.config_path, "w") as file:
57
- yaml.dump(self._config.dict(), file)
 
 
58
  except Exception as ex:
59
  print(f"Error in saving settings : {ex}")
60
 
 
3
  from models.settings import Settings
4
  from paths import FastStableDiffusionPaths
5
  from utils import get_models_from_text_file
6
+ from constants import (
7
+ OPENVINO_LCM_MODELS_FILE,
8
+ LCM_LORA_MODELS_FILE,
9
+ SD_MODELS_FILE,
10
+ LCM_MODELS_FILE,
11
+ )
12
+ from copy import deepcopy
13
 
14
 
15
  class AppSettings:
16
  def __init__(self):
17
  self.config_path = FastStableDiffusionPaths().get_app_settings_path()
18
+ self._stable_diffsuion_models = get_models_from_text_file(
19
+ FastStableDiffusionPaths().get_models_config_path(SD_MODELS_FILE)
20
+ )
21
+ self._lcm_lora_models = get_models_from_text_file(
22
+ FastStableDiffusionPaths().get_models_config_path(LCM_LORA_MODELS_FILE)
23
+ )
24
+ self._openvino_lcm_models = get_models_from_text_file(
25
+ FastStableDiffusionPaths().get_models_config_path(OPENVINO_LCM_MODELS_FILE)
26
+ )
27
+ self._lcm_models = get_models_from_text_file(
28
+ FastStableDiffusionPaths().get_models_config_path(LCM_MODELS_FILE)
29
+ )
30
 
31
  @property
32
  def settings(self):
 
40
  def openvino_lcm_models(self):
41
  return self._openvino_lcm_models
42
 
43
+ @property
44
+ def lcm_models(self):
45
+ return self._lcm_models
46
+
47
  @property
48
  def lcm_lora_models(self):
49
  return self._lcm_lora_models
50
 
51
+ def load(self, skip_file=False):
52
+ if skip_file:
53
+ print("Skipping config file")
54
+ settings_dict = self._load_default()
55
+ self._config = Settings.parse_obj(settings_dict)
56
+ else:
57
+ if not path.exists(self.config_path):
58
+ base_dir = path.dirname(self.config_path)
59
+ if not path.exists(base_dir):
60
+ makedirs(base_dir)
61
+ try:
62
+ print("Settings not found creating default settings")
63
+ with open(self.config_path, "w") as file:
64
+ yaml.dump(
65
+ self._load_default(),
66
+ file,
67
+ )
68
+ except Exception as ex:
69
+ print(f"Error in creating settings : {ex}")
70
+ exit()
71
  try:
72
+ with open(self.config_path) as file:
73
+ settings_dict = yaml.safe_load(file)
74
+ self._config = Settings.parse_obj(settings_dict)
 
 
 
75
  except Exception as ex:
76
+ print(f"Error in loading settings : {ex}")
 
 
 
 
 
 
 
77
 
78
  def save(self):
79
  try:
80
  with open(self.config_path, "w") as file:
81
+ tmp_cfg = deepcopy(self._config)
82
+ tmp_cfg.lcm_diffusion_setting.init_image = None
83
+ yaml.dump(tmp_cfg.dict(), file)
84
  except Exception as ex:
85
  print(f"Error in saving settings : {ex}")
86
 
backend/image_saver.py CHANGED
@@ -15,6 +15,7 @@ class ImageSaver:
15
  lcm_diffusion_setting: LCMDiffusionSetting = None,
16
  ) -> None:
17
  gen_id = uuid4()
 
18
  for index, image in enumerate(images):
19
  if not path.exists(output_path):
20
  mkdir(output_path)
@@ -33,7 +34,7 @@ class ImageSaver:
33
  if lcm_diffusion_setting:
34
  with open(path.join(out_path, f"{gen_id}.json"), "w") as json_file:
35
  json.dump(
36
- lcm_diffusion_setting.model_dump(),
37
  json_file,
38
  indent=4,
39
  )
 
15
  lcm_diffusion_setting: LCMDiffusionSetting = None,
16
  ) -> None:
17
  gen_id = uuid4()
18
+
19
  for index, image in enumerate(images):
20
  if not path.exists(output_path):
21
  mkdir(output_path)
 
34
  if lcm_diffusion_setting:
35
  with open(path.join(out_path, f"{gen_id}.json"), "w") as json_file:
36
  json.dump(
37
+ lcm_diffusion_setting.model_dump(exclude="init_image"),
38
  json_file,
39
  indent=4,
40
  )
backend/lcm_text_to_image.py CHANGED
@@ -1,52 +1,25 @@
1
  from typing import Any
2
- from diffusers import (
3
- DiffusionPipeline,
4
- AutoencoderTiny,
5
- LCMScheduler,
6
- UNet2DConditionModel,
7
- )
8
- from os import path
9
  import torch
10
  from backend.models.lcmdiffusion_setting import LCMDiffusionSetting
11
  import numpy as np
12
- from constants import (
13
- DEVICE,
14
- LCM_DEFAULT_MODEL,
15
- TAESD_MODEL,
16
- TAESDXL_MODEL,
17
- TAESD_MODEL_OPENVINO,
18
- )
19
- from huggingface_hub import model_info
20
  from backend.models.lcmdiffusion_setting import LCMLora
21
  from backend.device import is_openvino_device
22
-
23
- if is_openvino_device():
24
- from huggingface_hub import snapshot_download
25
- from optimum.intel.openvino.modeling_diffusion import OVModelVaeDecoder, OVBaseModel
26
-
27
- # from optimum.intel.openvino.modeling_diffusion import OVStableDiffusionPipeline
28
- from backend.lcmdiffusion.pipelines.openvino.lcm_ov_pipeline import (
29
- OVStableDiffusionPipeline,
30
- )
31
- from backend.lcmdiffusion.pipelines.openvino.lcm_scheduler import (
32
- LCMScheduler as OpenVinoLCMscheduler,
33
- )
34
-
35
- class CustomOVModelVaeDecoder(OVModelVaeDecoder):
36
- def __init__(
37
- self,
38
- model,
39
- parent_model,
40
- ov_config=None,
41
- model_dir=None,
42
- ):
43
- super(OVModelVaeDecoder, self).__init__(
44
- model,
45
- parent_model,
46
- ov_config,
47
- "vae_decoder",
48
- model_dir,
49
- )
50
 
51
 
52
  class LCMTextToImage:
@@ -60,95 +33,17 @@ class LCMTextToImage:
60
  self.previous_model_id = None
61
  self.previous_use_tae_sd = False
62
  self.previous_use_lcm_lora = False
 
 
 
 
 
 
63
  self.torch_data_type = (
64
  torch.float32 if is_openvino_device() or DEVICE == "mps" else torch.float16
65
  )
66
  print(f"Torch datatype : {self.torch_data_type}")
67
 
68
- def _get_lcm_pipeline(
69
- self,
70
- lcm_model_id: str,
71
- base_model_id: str,
72
- use_local_model: bool,
73
- ):
74
- pipeline = None
75
- unet = UNet2DConditionModel.from_pretrained(
76
- lcm_model_id,
77
- torch_dtype=torch.float32,
78
- local_files_only=use_local_model
79
- # resume_download=True,
80
- )
81
- pipeline = DiffusionPipeline.from_pretrained(
82
- base_model_id,
83
- unet=unet,
84
- torch_dtype=torch.float32,
85
- local_files_only=use_local_model
86
- # resume_download=True,
87
- )
88
- pipeline.scheduler = LCMScheduler.from_config(pipeline.scheduler.config)
89
- return pipeline
90
-
91
- def get_tiny_decoder_vae_model(self) -> str:
92
- pipeline_class = self.pipeline.__class__.__name__
93
- print(f"Pipeline class : {pipeline_class}")
94
- if (
95
- pipeline_class == "LatentConsistencyModelPipeline"
96
- or pipeline_class == "StableDiffusionPipeline"
97
- ):
98
- return TAESD_MODEL
99
- elif pipeline_class == "StableDiffusionXLPipeline":
100
- return TAESDXL_MODEL
101
- elif pipeline_class == "OVStableDiffusionPipeline":
102
- return TAESD_MODEL_OPENVINO
103
-
104
- def _get_lcm_model_pipeline(
105
- self,
106
- model_id: str,
107
- use_local_model,
108
- ):
109
- pipeline = None
110
- if model_id == LCM_DEFAULT_MODEL:
111
- pipeline = DiffusionPipeline.from_pretrained(
112
- model_id,
113
- local_files_only=use_local_model,
114
- )
115
- elif model_id == "latent-consistency/lcm-sdxl":
116
- pipeline = self._get_lcm_pipeline(
117
- model_id,
118
- "stabilityai/stable-diffusion-xl-base-1.0",
119
- use_local_model,
120
- )
121
-
122
- elif model_id == "latent-consistency/lcm-ssd-1b":
123
- pipeline = self._get_lcm_pipeline(
124
- model_id,
125
- "segmind/SSD-1B",
126
- use_local_model,
127
- )
128
- return pipeline
129
-
130
- def _get_lcm_lora_pipeline(
131
- self,
132
- base_model_id: str,
133
- lcm_lora_id: str,
134
- use_local_model: bool,
135
- ):
136
- pipeline = DiffusionPipeline.from_pretrained(
137
- base_model_id,
138
- torch_dtype=self.torch_data_type,
139
- local_files_only=use_local_model,
140
- )
141
- pipeline.load_lora_weights(
142
- lcm_lora_id,
143
- local_files_only=use_local_model,
144
- )
145
-
146
- pipeline.scheduler = LCMScheduler.from_config(pipeline.scheduler.config)
147
-
148
- pipeline.fuse_lora()
149
- pipeline.unet.to(memory_format=torch.channels_last)
150
- return pipeline
151
-
152
  def _pipeline_to_device(self):
153
  print(f"Pipeline device : {DEVICE}")
154
  print(f"Pipeline dtype : {self.torch_data_type}")
@@ -159,37 +54,53 @@ class LCMTextToImage:
159
 
160
  def _add_freeu(self):
161
  pipeline_class = self.pipeline.__class__.__name__
162
- if pipeline_class == "StableDiffusionPipeline":
163
- print("Add FreeU - SD")
164
- self.pipeline.enable_freeu(
165
- s1=0.9,
166
- s2=0.2,
167
- b1=1.2,
168
- b2=1.4,
169
- )
170
- elif pipeline_class == "StableDiffusionXLPipeline":
171
- print("Add FreeU - SDXL")
172
- self.pipeline.enable_freeu(
173
- s1=0.6,
174
- s2=0.4,
175
- b1=1.1,
176
- b2=1.2,
 
 
 
 
 
 
 
 
 
177
  )
178
 
179
  def init(
180
  self,
181
- model_id: str,
182
- use_openvino: bool = False,
183
  device: str = "cpu",
184
- use_local_model: bool = False,
185
- use_tiny_auto_encoder: bool = False,
186
- use_lora: bool = False,
187
- lcm_lora: LCMLora = LCMLora(),
188
  ) -> None:
189
  self.device = device
190
- self.use_openvino = use_openvino
191
- print(f"use_openvino {self.use_openvino}")
192
- print(f"is_openvino {is_openvino_device()}")
 
 
 
 
 
 
 
 
 
 
 
 
193
  if (
194
  self.pipeline is None
195
  or self.previous_model_id != model_id
@@ -197,77 +108,132 @@ class LCMTextToImage:
197
  or self.previous_lcm_lora_base_id != lcm_lora.base_model_id
198
  or self.previous_lcm_lora_id != lcm_lora.lcm_lora_id
199
  or self.previous_use_lcm_lora != use_lora
 
 
 
 
200
  ):
201
  if self.use_openvino and is_openvino_device():
202
  if self.pipeline:
203
  del self.pipeline
204
  self.pipeline = None
205
-
206
- self.pipeline = OVStableDiffusionPipeline.from_pretrained(
207
- model_id,
208
- local_files_only=use_local_model,
209
- ov_config={"CACHE_DIR": ""},
210
- device=DEVICE.upper(),
211
- )
212
-
213
- if use_tiny_auto_encoder:
214
- print("Using Tiny Auto Encoder (OpenVINO)")
215
- taesd_dir = snapshot_download(
216
- repo_id=self.get_tiny_decoder_vae_model(),
217
- local_files_only=use_local_model,
218
  )
219
- self.pipeline.vae_decoder = CustomOVModelVaeDecoder(
220
- model=OVBaseModel.load_model(
221
- f"{taesd_dir}/vae_decoder/openvino_model.xml"
222
- ),
223
- parent_model=self.pipeline,
224
- model_dir=taesd_dir,
 
 
225
  )
226
-
227
  else:
228
  if self.pipeline:
229
  del self.pipeline
230
  self.pipeline = None
 
 
 
231
 
232
  if use_lora:
233
- print("Init LCM-LoRA pipeline")
234
- self.pipeline = self._get_lcm_lora_pipeline(
 
 
235
  lcm_lora.base_model_id,
236
  lcm_lora.lcm_lora_id,
237
  use_local_model,
 
238
  )
239
  else:
240
- print("Init LCM Model pipeline")
241
- self.pipeline = self._get_lcm_model_pipeline(
242
  model_id,
243
  use_local_model,
244
  )
245
 
246
- if use_tiny_auto_encoder:
247
- vae_model = self.get_tiny_decoder_vae_model()
248
- print(f"Using Tiny Auto Encoder {vae_model}")
249
- self.pipeline.vae = AutoencoderTiny.from_pretrained(
250
- vae_model,
251
- torch_dtype=torch.float32,
252
- local_files_only=use_local_model,
253
  )
254
-
255
  self._pipeline_to_device()
256
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
257
  self.previous_model_id = model_id
 
258
  self.previous_use_tae_sd = use_tiny_auto_encoder
259
  self.previous_lcm_lora_base_id = lcm_lora.base_model_id
260
  self.previous_lcm_lora_id = lcm_lora.lcm_lora_id
261
  self.previous_use_lcm_lora = use_lora
262
- print(f"Model :{model_id}")
263
- print(f"Pipeline : {self.pipeline}")
264
- self.pipeline.scheduler = LCMScheduler.from_config(
265
- self.pipeline.scheduler.config,
266
- beta_start=0.001,
267
- beta_end=0.01,
268
- )
269
- if use_lora:
270
- self._add_freeu()
 
 
 
 
 
 
 
271
 
272
  def generate(
273
  self,
@@ -275,6 +241,19 @@ class LCMTextToImage:
275
  reshape: bool = False,
276
  ) -> Any:
277
  guidance_scale = lcm_diffusion_setting.guidance_scale
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  if lcm_diffusion_setting.use_seed:
279
  cur_seed = lcm_diffusion_setting.seed
280
  if self.use_openvino:
@@ -282,9 +261,10 @@ class LCMTextToImage:
282
  else:
283
  torch.manual_seed(cur_seed)
284
 
285
- if lcm_diffusion_setting.use_openvino and is_openvino_device():
 
286
  print("Using OpenVINO")
287
- if reshape:
288
  print("Reshape and compile")
289
  self.pipeline.reshape(
290
  batch_size=-1,
@@ -294,8 +274,17 @@ class LCMTextToImage:
294
  )
295
  self.pipeline.compile()
296
 
 
 
 
297
  if not lcm_diffusion_setting.use_safety_checker:
298
  self.pipeline.safety_checker = None
 
 
 
 
 
 
299
 
300
  if (
301
  not lcm_diffusion_setting.use_lcm_lora
@@ -306,24 +295,61 @@ class LCMTextToImage:
306
  guidance_scale = 1.0
307
 
308
  if lcm_diffusion_setting.use_openvino:
309
- result_images = self.pipeline(
310
- prompt=lcm_diffusion_setting.prompt,
311
- negative_prompt=lcm_diffusion_setting.negative_prompt,
312
- num_inference_steps=lcm_diffusion_setting.inference_steps,
313
- guidance_scale=guidance_scale,
314
- width=lcm_diffusion_setting.image_width,
315
- height=lcm_diffusion_setting.image_height,
316
- num_images_per_prompt=lcm_diffusion_setting.number_of_images,
317
- ).images
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
  else:
319
- result_images = self.pipeline(
320
- prompt=lcm_diffusion_setting.prompt,
321
- negative_prompt=lcm_diffusion_setting.negative_prompt,
322
- num_inference_steps=lcm_diffusion_setting.inference_steps,
323
- guidance_scale=guidance_scale,
324
- width=lcm_diffusion_setting.image_width,
325
- height=lcm_diffusion_setting.image_height,
326
- num_images_per_prompt=lcm_diffusion_setting.number_of_images,
327
- ).images
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
328
 
329
  return result_images
 
1
  from typing import Any
2
+ from diffusers import LCMScheduler
 
 
 
 
 
 
3
  import torch
4
  from backend.models.lcmdiffusion_setting import LCMDiffusionSetting
5
  import numpy as np
6
+ from constants import DEVICE
 
 
 
 
 
 
 
7
  from backend.models.lcmdiffusion_setting import LCMLora
8
  from backend.device import is_openvino_device
9
+ from backend.openvino.pipelines import (
10
+ get_ov_text_to_image_pipeline,
11
+ ov_load_taesd,
12
+ get_ov_image_to_image_pipeline,
13
+ )
14
+ from backend.pipelines.lcm import (
15
+ get_lcm_model_pipeline,
16
+ load_taesd,
17
+ get_image_to_image_pipeline,
18
+ )
19
+ from backend.pipelines.lcm_lora import get_lcm_lora_pipeline
20
+ from backend.models.lcmdiffusion_setting import DiffusionTask
21
+ from image_ops import resize_pil_image
22
+ from math import ceil
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
 
25
  class LCMTextToImage:
 
33
  self.previous_model_id = None
34
  self.previous_use_tae_sd = False
35
  self.previous_use_lcm_lora = False
36
+ self.previous_ov_model_id = ""
37
+ self.previous_safety_checker = False
38
+ self.previous_use_openvino = False
39
+ self.img_to_img_pipeline = None
40
+ self.is_openvino_init = False
41
+ self.task_type = DiffusionTask.text_to_image
42
  self.torch_data_type = (
43
  torch.float32 if is_openvino_device() or DEVICE == "mps" else torch.float16
44
  )
45
  print(f"Torch datatype : {self.torch_data_type}")
46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  def _pipeline_to_device(self):
48
  print(f"Pipeline device : {DEVICE}")
49
  print(f"Pipeline dtype : {self.torch_data_type}")
 
54
 
55
  def _add_freeu(self):
56
  pipeline_class = self.pipeline.__class__.__name__
57
+ if isinstance(self.pipeline.scheduler, LCMScheduler):
58
+ if pipeline_class == "StableDiffusionPipeline":
59
+ print("Add FreeU - SD")
60
+ self.pipeline.enable_freeu(
61
+ s1=0.9,
62
+ s2=0.2,
63
+ b1=1.2,
64
+ b2=1.4,
65
+ )
66
+ elif pipeline_class == "StableDiffusionXLPipeline":
67
+ print("Add FreeU - SDXL")
68
+ self.pipeline.enable_freeu(
69
+ s1=0.6,
70
+ s2=0.4,
71
+ b1=1.1,
72
+ b2=1.2,
73
+ )
74
+
75
+ def _update_lcm_scheduler_params(self):
76
+ if isinstance(self.pipeline.scheduler, LCMScheduler):
77
+ self.pipeline.scheduler = LCMScheduler.from_config(
78
+ self.pipeline.scheduler.config,
79
+ beta_start=0.001,
80
+ beta_end=0.01,
81
  )
82
 
83
  def init(
84
  self,
 
 
85
  device: str = "cpu",
86
+ lcm_diffusion_setting: LCMDiffusionSetting = LCMDiffusionSetting(),
 
 
 
87
  ) -> None:
88
  self.device = device
89
+ self.use_openvino = lcm_diffusion_setting.use_openvino
90
+ model_id = lcm_diffusion_setting.lcm_model_id
91
+ use_local_model = lcm_diffusion_setting.use_offline_model
92
+ use_tiny_auto_encoder = lcm_diffusion_setting.use_tiny_auto_encoder
93
+ use_lora = lcm_diffusion_setting.use_lcm_lora
94
+ lcm_lora: LCMLora = lcm_diffusion_setting.lcm_lora
95
+ ov_model_id = lcm_diffusion_setting.openvino_lcm_model_id
96
+
97
+ if lcm_diffusion_setting.diffusion_task == DiffusionTask.image_to_image.value:
98
+ lcm_diffusion_setting.init_image = resize_pil_image(
99
+ lcm_diffusion_setting.init_image,
100
+ lcm_diffusion_setting.image_width,
101
+ lcm_diffusion_setting.image_height,
102
+ )
103
+
104
  if (
105
  self.pipeline is None
106
  or self.previous_model_id != model_id
 
108
  or self.previous_lcm_lora_base_id != lcm_lora.base_model_id
109
  or self.previous_lcm_lora_id != lcm_lora.lcm_lora_id
110
  or self.previous_use_lcm_lora != use_lora
111
+ or self.previous_ov_model_id != ov_model_id
112
+ or self.previous_safety_checker != lcm_diffusion_setting.use_safety_checker
113
+ or self.previous_use_openvino != lcm_diffusion_setting.use_openvino
114
+ or self.previous_task_type != lcm_diffusion_setting.diffusion_task
115
  ):
116
  if self.use_openvino and is_openvino_device():
117
  if self.pipeline:
118
  del self.pipeline
119
  self.pipeline = None
120
+ self.is_openvino_init = True
121
+ if (
122
+ lcm_diffusion_setting.diffusion_task
123
+ == DiffusionTask.text_to_image.value
124
+ ):
125
+ print(f"***** Init Text to image (OpenVINO) - {ov_model_id} *****")
126
+ self.pipeline = get_ov_text_to_image_pipeline(
127
+ ov_model_id,
128
+ use_local_model,
 
 
 
 
129
  )
130
+ elif (
131
+ lcm_diffusion_setting.diffusion_task
132
+ == DiffusionTask.image_to_image.value
133
+ ):
134
+ print(f"***** Image to image (OpenVINO) - {ov_model_id} *****")
135
+ self.pipeline = get_ov_image_to_image_pipeline(
136
+ ov_model_id,
137
+ use_local_model,
138
  )
 
139
  else:
140
  if self.pipeline:
141
  del self.pipeline
142
  self.pipeline = None
143
+ if self.img_to_img_pipeline:
144
+ del self.img_to_img_pipeline
145
+ self.img_to_img_pipeline = None
146
 
147
  if use_lora:
148
+ print(
149
+ f"***** Init LCM-LoRA pipeline - {lcm_lora.base_model_id} *****"
150
+ )
151
+ self.pipeline = get_lcm_lora_pipeline(
152
  lcm_lora.base_model_id,
153
  lcm_lora.lcm_lora_id,
154
  use_local_model,
155
+ torch_data_type=self.torch_data_type,
156
  )
157
  else:
158
+ print(f"***** Init LCM Model pipeline - {model_id} *****")
159
+ self.pipeline = get_lcm_model_pipeline(
160
  model_id,
161
  use_local_model,
162
  )
163
 
164
+ if (
165
+ lcm_diffusion_setting.diffusion_task
166
+ == DiffusionTask.image_to_image.value
167
+ ):
168
+ self.img_to_img_pipeline = get_image_to_image_pipeline(
169
+ self.pipeline
 
170
  )
 
171
  self._pipeline_to_device()
172
 
173
+ if use_tiny_auto_encoder:
174
+ if self.use_openvino and is_openvino_device():
175
+ print("Using Tiny Auto Encoder (OpenVINO)")
176
+ ov_load_taesd(
177
+ self.pipeline,
178
+ use_local_model,
179
+ )
180
+ else:
181
+ print("Using Tiny Auto Encoder")
182
+ if (
183
+ lcm_diffusion_setting.diffusion_task
184
+ == DiffusionTask.text_to_image.value
185
+ ):
186
+ load_taesd(
187
+ self.pipeline,
188
+ use_local_model,
189
+ self.torch_data_type,
190
+ )
191
+ elif (
192
+ lcm_diffusion_setting.diffusion_task
193
+ == DiffusionTask.image_to_image.value
194
+ ):
195
+ load_taesd(
196
+ self.img_to_img_pipeline,
197
+ use_local_model,
198
+ self.torch_data_type,
199
+ )
200
+
201
+ if (
202
+ lcm_diffusion_setting.diffusion_task
203
+ == DiffusionTask.image_to_image.value
204
+ and lcm_diffusion_setting.use_openvino
205
+ ):
206
+ self.pipeline.scheduler = LCMScheduler.from_config(
207
+ self.pipeline.scheduler.config,
208
+ )
209
+ else:
210
+ self._update_lcm_scheduler_params()
211
+
212
+ if use_lora:
213
+ self._add_freeu()
214
+
215
  self.previous_model_id = model_id
216
+ self.previous_ov_model_id = ov_model_id
217
  self.previous_use_tae_sd = use_tiny_auto_encoder
218
  self.previous_lcm_lora_base_id = lcm_lora.base_model_id
219
  self.previous_lcm_lora_id = lcm_lora.lcm_lora_id
220
  self.previous_use_lcm_lora = use_lora
221
+ self.previous_safety_checker = lcm_diffusion_setting.use_safety_checker
222
+ self.previous_use_openvino = lcm_diffusion_setting.use_openvino
223
+ self.previous_task_type = lcm_diffusion_setting.diffusion_task
224
+ if (
225
+ lcm_diffusion_setting.diffusion_task
226
+ == DiffusionTask.text_to_image.value
227
+ ):
228
+ print(f"Pipeline : {self.pipeline}")
229
+ elif (
230
+ lcm_diffusion_setting.diffusion_task
231
+ == DiffusionTask.image_to_image.value
232
+ ):
233
+ if self.use_openvino and is_openvino_device():
234
+ print(f"Pipeline : {self.pipeline}")
235
+ else:
236
+ print(f"Pipeline : {self.img_to_img_pipeline}")
237
 
238
  def generate(
239
  self,
 
241
  reshape: bool = False,
242
  ) -> Any:
243
  guidance_scale = lcm_diffusion_setting.guidance_scale
244
+ img_to_img_inference_steps = lcm_diffusion_setting.inference_steps
245
+ check_step_value = int(
246
+ lcm_diffusion_setting.inference_steps * lcm_diffusion_setting.strength
247
+ )
248
+ if (
249
+ lcm_diffusion_setting.diffusion_task == DiffusionTask.image_to_image.value
250
+ and check_step_value < 1
251
+ ):
252
+ img_to_img_inference_steps = ceil(1 / lcm_diffusion_setting.strength)
253
+ print(
254
+ f"Strength: {lcm_diffusion_setting.strength},{img_to_img_inference_steps}"
255
+ )
256
+
257
  if lcm_diffusion_setting.use_seed:
258
  cur_seed = lcm_diffusion_setting.seed
259
  if self.use_openvino:
 
261
  else:
262
  torch.manual_seed(cur_seed)
263
 
264
+ is_openvino_pipe = lcm_diffusion_setting.use_openvino and is_openvino_device()
265
+ if is_openvino_pipe:
266
  print("Using OpenVINO")
267
+ if reshape and not self.is_openvino_init:
268
  print("Reshape and compile")
269
  self.pipeline.reshape(
270
  batch_size=-1,
 
274
  )
275
  self.pipeline.compile()
276
 
277
+ if self.is_openvino_init:
278
+ self.is_openvino_init = False
279
+
280
  if not lcm_diffusion_setting.use_safety_checker:
281
  self.pipeline.safety_checker = None
282
+ if (
283
+ lcm_diffusion_setting.diffusion_task
284
+ == DiffusionTask.image_to_image.value
285
+ and not is_openvino_pipe
286
+ ):
287
+ self.img_to_img_pipeline.safety_checker = None
288
 
289
  if (
290
  not lcm_diffusion_setting.use_lcm_lora
 
295
  guidance_scale = 1.0
296
 
297
  if lcm_diffusion_setting.use_openvino:
298
+ if (
299
+ lcm_diffusion_setting.diffusion_task
300
+ == DiffusionTask.text_to_image.value
301
+ ):
302
+ result_images = self.pipeline(
303
+ prompt=lcm_diffusion_setting.prompt,
304
+ negative_prompt=lcm_diffusion_setting.negative_prompt,
305
+ num_inference_steps=lcm_diffusion_setting.inference_steps,
306
+ guidance_scale=guidance_scale,
307
+ width=lcm_diffusion_setting.image_width,
308
+ height=lcm_diffusion_setting.image_height,
309
+ num_images_per_prompt=lcm_diffusion_setting.number_of_images,
310
+ ).images
311
+ elif (
312
+ lcm_diffusion_setting.diffusion_task
313
+ == DiffusionTask.image_to_image.value
314
+ ):
315
+ result_images = self.pipeline(
316
+ image=lcm_diffusion_setting.init_image,
317
+ strength=lcm_diffusion_setting.strength,
318
+ prompt=lcm_diffusion_setting.prompt,
319
+ negative_prompt=lcm_diffusion_setting.negative_prompt,
320
+ num_inference_steps=img_to_img_inference_steps * 3,
321
+ guidance_scale=guidance_scale,
322
+ num_images_per_prompt=lcm_diffusion_setting.number_of_images,
323
+ ).images
324
+
325
  else:
326
+ if (
327
+ lcm_diffusion_setting.diffusion_task
328
+ == DiffusionTask.text_to_image.value
329
+ ):
330
+ result_images = self.pipeline(
331
+ prompt=lcm_diffusion_setting.prompt,
332
+ negative_prompt=lcm_diffusion_setting.negative_prompt,
333
+ num_inference_steps=lcm_diffusion_setting.inference_steps,
334
+ guidance_scale=guidance_scale,
335
+ width=lcm_diffusion_setting.image_width,
336
+ height=lcm_diffusion_setting.image_height,
337
+ num_images_per_prompt=lcm_diffusion_setting.number_of_images,
338
+ ).images
339
+ elif (
340
+ lcm_diffusion_setting.diffusion_task
341
+ == DiffusionTask.image_to_image.value
342
+ ):
343
+ result_images = self.img_to_img_pipeline(
344
+ image=lcm_diffusion_setting.init_image,
345
+ strength=lcm_diffusion_setting.strength,
346
+ prompt=lcm_diffusion_setting.prompt,
347
+ negative_prompt=lcm_diffusion_setting.negative_prompt,
348
+ num_inference_steps=img_to_img_inference_steps,
349
+ guidance_scale=guidance_scale,
350
+ width=lcm_diffusion_setting.image_width,
351
+ height=lcm_diffusion_setting.image_height,
352
+ num_images_per_prompt=lcm_diffusion_setting.number_of_images,
353
+ ).images
354
 
355
  return result_images
backend/models/lcmdiffusion_setting.py CHANGED
@@ -1,12 +1,19 @@
1
- from typing import Optional
2
-
3
  from pydantic import BaseModel
4
  from constants import LCM_DEFAULT_MODEL, LCM_DEFAULT_MODEL_OPENVINO
5
 
6
 
7
  class LCMLora(BaseModel):
8
- base_model_id: str = ""
9
- lcm_lora_id: str = ""
 
 
 
 
 
 
 
10
 
11
 
12
  class LCMDiffusionSetting(BaseModel):
@@ -19,11 +26,14 @@ class LCMDiffusionSetting(BaseModel):
19
  use_openvino: bool = False
20
  prompt: str = ""
21
  negative_prompt: str = ""
 
 
22
  image_height: Optional[int] = 512
23
  image_width: Optional[int] = 512
24
- inference_steps: Optional[int] = 4
25
  guidance_scale: Optional[float] = 1
26
  number_of_images: Optional[int] = 1
27
- seed: Optional[int] = -1
28
  use_seed: bool = False
29
  use_safety_checker: bool = False
 
 
1
+ from typing import Optional, Any
2
+ from enum import Enum
3
  from pydantic import BaseModel
4
  from constants import LCM_DEFAULT_MODEL, LCM_DEFAULT_MODEL_OPENVINO
5
 
6
 
7
  class LCMLora(BaseModel):
8
+ base_model_id: str = "Lykon/dreamshaper-8"
9
+ lcm_lora_id: str = "latent-consistency/lcm-lora-sdv1-5"
10
+
11
+
12
+ class DiffusionTask(str, Enum):
13
+ """Diffusion task types"""
14
+
15
+ text_to_image = "text_to_image"
16
+ image_to_image = "image_to_image"
17
 
18
 
19
  class LCMDiffusionSetting(BaseModel):
 
26
  use_openvino: bool = False
27
  prompt: str = ""
28
  negative_prompt: str = ""
29
+ init_image: Any = None
30
+ strength: Optional[float] = 0.6
31
  image_height: Optional[int] = 512
32
  image_width: Optional[int] = 512
33
+ inference_steps: Optional[int] = 1
34
  guidance_scale: Optional[float] = 1
35
  number_of_images: Optional[int] = 1
36
+ seed: Optional[int] = 123123
37
  use_seed: bool = False
38
  use_safety_checker: bool = False
39
+ diffusion_task: str = DiffusionTask.text_to_image.value
configs/openvino-lcm-models.txt CHANGED
@@ -1,2 +1,4 @@
 
 
1
  rupeshs/LCM-dreamshaper-v7-openvino
2
  Disty0/LCM_SoteMix
 
1
+ rupeshs/sd-turbo-openvino
2
+ rupeshs/sdxl-turbo-openvino-int8
3
  rupeshs/LCM-dreamshaper-v7-openvino
4
  Disty0/LCM_SoteMix
constants.py CHANGED
@@ -1,8 +1,8 @@
1
  from os import environ
2
 
3
- APP_VERSION = "v1.0.0 beta 16"
4
- LCM_DEFAULT_MODEL = "SimianLuo/LCM_Dreamshaper_v7"
5
- LCM_DEFAULT_MODEL_OPENVINO = "rupeshs/LCM-dreamshaper-v7-openvino"
6
  APP_NAME = "FastSD CPU"
7
  APP_SETTINGS_FILE = "settings.yaml"
8
  RESULTS_DIRECTORY = "results"
@@ -14,3 +14,5 @@ OPENVINO_LCM_MODELS_FILE = "openvino-lcm-models.txt"
14
  TAESD_MODEL = "madebyollin/taesd"
15
  TAESDXL_MODEL = "madebyollin/taesdxl"
16
  TAESD_MODEL_OPENVINO = "deinferno/taesd-openvino"
 
 
 
1
  from os import environ
2
 
3
+ APP_VERSION = "v1.0.0 beta 23"
4
+ LCM_DEFAULT_MODEL = "stabilityai/sd-turbo"
5
+ LCM_DEFAULT_MODEL_OPENVINO = "rupeshs/sd-turbo-openvino"
6
  APP_NAME = "FastSD CPU"
7
  APP_SETTINGS_FILE = "settings.yaml"
8
  RESULTS_DIRECTORY = "results"
 
14
  TAESD_MODEL = "madebyollin/taesd"
15
  TAESDXL_MODEL = "madebyollin/taesdxl"
16
  TAESD_MODEL_OPENVINO = "deinferno/taesd-openvino"
17
+ LCM_MODELS_FILE = "lcm-models.txt"
18
+ TAESDXL_MODEL_OPENVINO = "rupeshs/taesdxl-openvino"
context.py CHANGED
@@ -23,17 +23,15 @@ class Context:
23
  device: str = "cpu",
24
  ) -> Any:
25
  tick = perf_counter()
 
 
 
26
  pprint(settings.lcm_diffusion_setting.model_dump())
27
  if not settings.lcm_diffusion_setting.lcm_lora:
28
  return None
29
  self.lcm_text_to_image.init(
30
- settings.lcm_diffusion_setting.lcm_model_id,
31
- settings.lcm_diffusion_setting.use_openvino,
32
  device,
33
- settings.lcm_diffusion_setting.use_offline_model,
34
- settings.lcm_diffusion_setting.use_tiny_auto_encoder,
35
- settings.lcm_diffusion_setting.use_lcm_lora,
36
- settings.lcm_diffusion_setting.lcm_lora,
37
  )
38
  images = self.lcm_text_to_image.generate(
39
  settings.lcm_diffusion_setting,
@@ -45,5 +43,5 @@ class Context:
45
  images=images,
46
  lcm_diffusion_setting=settings.lcm_diffusion_setting,
47
  )
48
- print(f"Elapsed time : {elapsed:.2f} seconds")
49
  return images
 
23
  device: str = "cpu",
24
  ) -> Any:
25
  tick = perf_counter()
26
+ from state import get_settings
27
+
28
+ get_settings().save()
29
  pprint(settings.lcm_diffusion_setting.model_dump())
30
  if not settings.lcm_diffusion_setting.lcm_lora:
31
  return None
32
  self.lcm_text_to_image.init(
 
 
33
  device,
34
+ settings.lcm_diffusion_setting,
 
 
 
35
  )
36
  images = self.lcm_text_to_image.generate(
37
  settings.lcm_diffusion_setting,
 
43
  images=images,
44
  lcm_diffusion_setting=settings.lcm_diffusion_setting,
45
  )
46
+ print(f"Latency : {elapsed:.2f} seconds")
47
  return images
frontend/gui/app_window.py CHANGED
@@ -35,7 +35,7 @@ from context import Context
35
  from models.interface_types import InterfaceType
36
  from constants import DEVICE
37
  from frontend.utils import enable_openvino_controls, get_valid_model_id
38
- from backend.lcm_models import get_available_models
39
 
40
  # DPI scale fix
41
  QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)
@@ -100,6 +100,13 @@ class MainWindow(QMainWindow):
100
  self.use_lcm_lora.setChecked(
101
  self.config.settings.lcm_diffusion_setting.use_lcm_lora
102
  )
 
 
 
 
 
 
 
103
  self.base_model_id.setCurrentText(
104
  get_valid_model_id(
105
  self.config.stable_diffsuion_models,
@@ -116,6 +123,7 @@ class MainWindow(QMainWindow):
116
  get_valid_model_id(
117
  self.config.openvino_lcm_models,
118
  self.config.settings.lcm_diffusion_setting.openvino_lcm_model_id,
 
119
  )
120
  )
121
  self.neg_prompt.setEnabled(
@@ -193,10 +201,9 @@ class MainWindow(QMainWindow):
193
  def create_settings_tab(self):
194
  self.lcm_model_label = QLabel("Latent Consistency Model:")
195
  # self.lcm_model = QLineEdit(LCM_DEFAULT_MODEL)
196
- lcm_models = get_available_models()
197
  self.lcm_model = QComboBox(self)
198
- for model in lcm_models:
199
- self.lcm_model.addItem(model)
200
 
201
  self.use_lcm_lora = QCheckBox("Use LCM LoRA")
202
  self.use_lcm_lora.setChecked(False)
@@ -303,6 +310,7 @@ class MainWindow(QMainWindow):
303
  vlayout = QVBoxLayout()
304
  vspacer = QSpacerItem(20, 20, QSizePolicy.Minimum, QSizePolicy.Expanding)
305
  vlayout.addItem(hspacer)
 
306
  vlayout.addWidget(self.lcm_model_label)
307
  vlayout.addWidget(self.lcm_model)
308
  vlayout.addWidget(self.use_local_model_folder)
@@ -415,6 +423,10 @@ class MainWindow(QMainWindow):
415
  height_txt = self.height.itemText(index)
416
  self.config.settings.lcm_diffusion_setting.image_height = int(height_txt)
417
 
 
 
 
 
418
  def on_base_model_id_changed(self, index):
419
  model_id = self.base_model_id.itemText(index)
420
  self.config.settings.lcm_diffusion_setting.lcm_lora.base_model_id = model_id
@@ -536,7 +548,9 @@ class MainWindow(QMainWindow):
536
  self.previous_num_of_images,
537
  self.config.settings.lcm_diffusion_setting.number_of_images,
538
  )
539
-
 
 
540
  images = self.context.generate_text_to_image(
541
  self.config.settings,
542
  reshape_required,
 
35
  from models.interface_types import InterfaceType
36
  from constants import DEVICE
37
  from frontend.utils import enable_openvino_controls, get_valid_model_id
38
+ from backend.models.lcmdiffusion_setting import DiffusionTask
39
 
40
  # DPI scale fix
41
  QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)
 
100
  self.use_lcm_lora.setChecked(
101
  self.config.settings.lcm_diffusion_setting.use_lcm_lora
102
  )
103
+ self.lcm_model.setCurrentText(
104
+ get_valid_model_id(
105
+ self.config.lcm_models,
106
+ self.config.settings.lcm_diffusion_setting.lcm_model_id,
107
+ LCM_DEFAULT_MODEL,
108
+ )
109
+ )
110
  self.base_model_id.setCurrentText(
111
  get_valid_model_id(
112
  self.config.stable_diffsuion_models,
 
123
  get_valid_model_id(
124
  self.config.openvino_lcm_models,
125
  self.config.settings.lcm_diffusion_setting.openvino_lcm_model_id,
126
+ LCM_DEFAULT_MODEL_OPENVINO,
127
  )
128
  )
129
  self.neg_prompt.setEnabled(
 
201
  def create_settings_tab(self):
202
  self.lcm_model_label = QLabel("Latent Consistency Model:")
203
  # self.lcm_model = QLineEdit(LCM_DEFAULT_MODEL)
 
204
  self.lcm_model = QComboBox(self)
205
+ self.lcm_model.addItems(self.config.lcm_models)
206
+ self.lcm_model.currentIndexChanged.connect(self.on_lcm_model_changed)
207
 
208
  self.use_lcm_lora = QCheckBox("Use LCM LoRA")
209
  self.use_lcm_lora.setChecked(False)
 
310
  vlayout = QVBoxLayout()
311
  vspacer = QSpacerItem(20, 20, QSizePolicy.Minimum, QSizePolicy.Expanding)
312
  vlayout.addItem(hspacer)
313
+ vlayout.setSpacing(3)
314
  vlayout.addWidget(self.lcm_model_label)
315
  vlayout.addWidget(self.lcm_model)
316
  vlayout.addWidget(self.use_local_model_folder)
 
423
  height_txt = self.height.itemText(index)
424
  self.config.settings.lcm_diffusion_setting.image_height = int(height_txt)
425
 
426
+ def on_lcm_model_changed(self, index):
427
+ model_id = self.lcm_model.itemText(index)
428
+ self.config.settings.lcm_diffusion_setting.lcm_model_id = model_id
429
+
430
  def on_base_model_id_changed(self, index):
431
  model_id = self.base_model_id.itemText(index)
432
  self.config.settings.lcm_diffusion_setting.lcm_lora.base_model_id = model_id
 
548
  self.previous_num_of_images,
549
  self.config.settings.lcm_diffusion_setting.number_of_images,
550
  )
551
+ self.config.settings.lcm_diffusion_setting.diffusion_task = (
552
+ DiffusionTask.text_to_image.value
553
+ )
554
  images = self.context.generate_text_to_image(
555
  self.config.settings,
556
  reshape_required,
frontend/utils.py CHANGED
@@ -34,12 +34,16 @@ def enable_openvino_controls() -> bool:
34
  def get_valid_model_id(
35
  models: List,
36
  model_id: str,
 
37
  ) -> str:
38
  if len(models) == 0:
39
  print("Error: model configuration file is empty,please add some models.")
40
  return ""
41
  if model_id == "":
42
- return models[0]
 
 
 
43
 
44
  if model_id in models:
45
  return model_id
 
34
  def get_valid_model_id(
35
  models: List,
36
  model_id: str,
37
+ default_model: str = "",
38
  ) -> str:
39
  if len(models) == 0:
40
  print("Error: model configuration file is empty,please add some models.")
41
  return ""
42
  if model_id == "":
43
+ if default_model:
44
+ return default_model
45
+ else:
46
+ return models[0]
47
 
48
  if model_id in models:
49
  return model_id
frontend/webui/css/style.css CHANGED
@@ -5,10 +5,8 @@ footer {
5
  #generate_button {
6
  color: white;
7
  border-color: #007bff;
8
- background: #007bff;
9
- width: 150px;
10
- margin-top: 38px;
11
- height: 80px;
12
  }
13
 
14
  #save_button {
 
5
  #generate_button {
6
  color: white;
7
  border-color: #007bff;
8
+ background: #2563eb;
9
+
 
 
10
  }
11
 
12
  #save_button {
frontend/webui/hf_demo.py CHANGED
@@ -122,7 +122,7 @@ with gr.Blocks(css=css) as demo:
122
  with gr.Accordion("Advanced options", open=False):
123
  steps = gr.Slider(
124
  label="Steps",
125
- value=3 if is_openvino_device() else 3,
126
  minimum=1,
127
  maximum=4,
128
  step=1,
 
122
  with gr.Accordion("Advanced options", open=False):
123
  steps = gr.Slider(
124
  label="Steps",
125
+ value=1,
126
  minimum=1,
127
  maximum=4,
128
  step=1,
frontend/webui/realtime_ui.py CHANGED
@@ -12,7 +12,7 @@ from backend.device import is_openvino_device
12
 
13
  lcm_text_to_image = LCMTextToImage()
14
  lcm_lora = LCMLora(
15
- base_model_id="Lykon/dreamshaper-7",
16
  lcm_lora_id="latent-consistency/lcm-lora-sdv1-5",
17
  )
18
 
@@ -35,14 +35,8 @@ def predict(
35
  steps,
36
  seed,
37
  ):
38
- lcm_text_to_image.init(
39
- model_id=LCM_DEFAULT_MODEL_OPENVINO,
40
- use_lora=True,
41
- lcm_lora=lcm_lora,
42
- use_openvino=True if is_openvino_device() else False,
43
- )
44
-
45
  lcm_diffusion_setting = LCMDiffusionSetting()
 
46
  lcm_diffusion_setting.prompt = prompt
47
  lcm_diffusion_setting.guidance_scale = 1.0
48
  lcm_diffusion_setting.inference_steps = steps
@@ -51,7 +45,12 @@ def predict(
51
  lcm_diffusion_setting.image_width = 256 if is_openvino_device() else 512
52
  lcm_diffusion_setting.image_height = 256 if is_openvino_device() else 512
53
  lcm_diffusion_setting.use_openvino = True if is_openvino_device() else False
 
 
 
 
54
  start = perf_counter()
 
55
  images = lcm_text_to_image.generate(lcm_diffusion_setting)
56
  latency = perf_counter() - start
57
  print(f"Latency: {latency:.2f} seconds")
 
12
 
13
  lcm_text_to_image = LCMTextToImage()
14
  lcm_lora = LCMLora(
15
+ base_model_id="Lykon/dreamshaper-8",
16
  lcm_lora_id="latent-consistency/lcm-lora-sdv1-5",
17
  )
18
 
 
35
  steps,
36
  seed,
37
  ):
 
 
 
 
 
 
 
38
  lcm_diffusion_setting = LCMDiffusionSetting()
39
+ lcm_diffusion_setting.openvino_lcm_model_id = "rupeshs/LCM-dreamshaper-v7-openvino"
40
  lcm_diffusion_setting.prompt = prompt
41
  lcm_diffusion_setting.guidance_scale = 1.0
42
  lcm_diffusion_setting.inference_steps = steps
 
45
  lcm_diffusion_setting.image_width = 256 if is_openvino_device() else 512
46
  lcm_diffusion_setting.image_height = 256 if is_openvino_device() else 512
47
  lcm_diffusion_setting.use_openvino = True if is_openvino_device() else False
48
+ lcm_text_to_image.init(
49
+ DEVICE,
50
+ lcm_diffusion_setting,
51
+ )
52
  start = perf_counter()
53
+
54
  images = lcm_text_to_image.generate(lcm_diffusion_setting)
55
  latency = perf_counter() - start
56
  print(f"Latency: {latency:.2f} seconds")
frontend/webui/text_to_image_ui.py CHANGED
@@ -1,19 +1,15 @@
1
- from typing import Any
2
  import gradio as gr
3
-
4
- from backend.models.lcmdiffusion_setting import LCMDiffusionSetting
5
- from context import Context
6
  from models.interface_types import InterfaceType
7
- from app_settings import Settings
8
- from constants import LCM_DEFAULT_MODEL, LCM_DEFAULT_MODEL_OPENVINO
9
- from frontend.utils import is_reshape_required
10
- from app_settings import AppSettings
11
  from constants import DEVICE
12
- from frontend.utils import enable_openvino_controls
13
-
14
- random_enabled = True
 
15
 
16
- context = Context(InterfaceType.WEBUI)
 
17
  previous_width = 0
18
  previous_height = 0
19
  previous_model_id = ""
@@ -22,42 +18,20 @@ previous_num_of_images = 0
22
 
23
  def generate_text_to_image(
24
  prompt,
25
- image_height,
26
- image_width,
27
- inference_steps,
28
- guidance_scale,
29
- num_images,
30
- seed,
31
- use_openvino,
32
- use_safety_checker,
33
- tiny_auto_encoder_checkbox,
34
  ) -> Any:
35
- global previous_height, previous_width, previous_model_id, previous_num_of_images
36
- model_id = LCM_DEFAULT_MODEL
37
- if use_openvino:
38
- model_id = LCM_DEFAULT_MODEL_OPENVINO
39
-
40
- use_seed = True if seed != -1 else False
41
-
42
- lcm_diffusion_settings = LCMDiffusionSetting(
43
- lcm_model_id=model_id,
44
- prompt=prompt,
45
- image_height=image_height,
46
- image_width=image_width,
47
- inference_steps=inference_steps,
48
- guidance_scale=guidance_scale,
49
- number_of_images=num_images,
50
- seed=seed,
51
- use_openvino=use_openvino,
52
- use_safety_checker=use_safety_checker,
53
- use_seed=use_seed,
54
- use_tiny_auto_encoder=tiny_auto_encoder_checkbox,
55
- )
56
- settings = Settings(
57
- lcm_diffusion_setting=lcm_diffusion_settings,
58
  )
 
59
  reshape = False
60
- if use_openvino:
 
 
 
61
  reshape = is_reshape_required(
62
  previous_width,
63
  image_width,
@@ -68,39 +42,37 @@ def generate_text_to_image(
68
  previous_num_of_images,
69
  num_images,
70
  )
71
- images = context.generate_text_to_image(
72
- settings,
73
- reshape,
74
- DEVICE,
75
- )
 
 
 
 
 
 
 
 
 
76
  previous_width = image_width
77
  previous_height = image_height
78
  previous_model_id = model_id
79
  previous_num_of_images = num_images
80
-
81
  return images
82
 
83
 
84
- def get_text_to_image_ui(app_settings: AppSettings) -> None:
85
  with gr.Blocks():
86
  with gr.Row():
87
  with gr.Column():
88
-
89
- def random_seed():
90
- global random_enabled
91
- random_enabled = not random_enabled
92
- seed_val = -1
93
- if not random_enabled:
94
- seed_val = 42
95
- return gr.Number.update(
96
- interactive=not random_enabled, value=seed_val
97
- )
98
-
99
  with gr.Row():
100
  prompt = gr.Textbox(
101
- label="Describe the image you'd like to see",
102
  lines=3,
103
  placeholder="A fantasy landscape",
 
104
  )
105
 
106
  generate_btn = gr.Button(
@@ -108,68 +80,13 @@ def get_text_to_image_ui(app_settings: AppSettings) -> None:
108
  elem_id="generate_button",
109
  scale=0,
110
  )
111
- num_inference_steps = gr.Slider(
112
- 1, 25, value=4, step=1, label="Inference Steps"
113
- )
114
- image_height = gr.Slider(
115
- 256, 768, value=512, step=256, label="Image Height"
116
- )
117
- image_width = gr.Slider(
118
- 256, 768, value=512, step=256, label="Image Width"
119
- )
120
- num_images = gr.Slider(
121
- 1,
122
- 50,
123
- value=1,
124
- step=1,
125
- label="Number of images to generate",
126
  )
127
- with gr.Accordion("Advanced options", open=False):
128
- guidance_scale = gr.Slider(
129
- 1.0, 2.0, value=1.0, step=0.5, label="Guidance Scale"
130
- )
131
-
132
- seed = gr.Number(
133
- label="Seed",
134
- value=-1,
135
- precision=0,
136
- interactive=False,
137
- )
138
- seed_checkbox = gr.Checkbox(
139
- label="Use random seed",
140
- value=True,
141
- interactive=True,
142
- )
143
 
144
- openvino_checkbox = gr.Checkbox(
145
- label="Use OpenVINO",
146
- value=False,
147
- interactive=enable_openvino_controls(),
148
- )
149
-
150
- safety_checker_checkbox = gr.Checkbox(
151
- label="Use Safety Checker",
152
- value=True,
153
- interactive=True,
154
- )
155
- tiny_auto_encoder_checkbox = gr.Checkbox(
156
- label="Use tiny auto encoder for SD",
157
- value=False,
158
- interactive=True,
159
- )
160
-
161
- input_params = [
162
- prompt,
163
- image_height,
164
- image_width,
165
- num_inference_steps,
166
- guidance_scale,
167
- num_images,
168
- seed,
169
- openvino_checkbox,
170
- safety_checker_checkbox,
171
- tiny_auto_encoder_checkbox,
172
- ]
173
 
174
  with gr.Column():
175
  output = gr.Gallery(
@@ -177,9 +94,8 @@ def get_text_to_image_ui(app_settings: AppSettings) -> None:
177
  show_label=True,
178
  elem_id="gallery",
179
  columns=2,
 
180
  )
181
-
182
- seed_checkbox.change(fn=random_seed, outputs=seed)
183
  generate_btn.click(
184
  fn=generate_text_to_image,
185
  inputs=input_params,
 
 
1
  import gradio as gr
2
+ from typing import Any
3
+ from backend.models.lcmdiffusion_setting import DiffusionTask
 
4
  from models.interface_types import InterfaceType
 
 
 
 
5
  from constants import DEVICE
6
+ from state import get_settings, get_context
7
+ from frontend.utils import is_reshape_required
8
+ from concurrent.futures import ThreadPoolExecutor
9
+ from pprint import pprint
10
 
11
+ app_settings = get_settings()
12
+ context = get_context(InterfaceType.WEBUI)
13
  previous_width = 0
14
  previous_height = 0
15
  previous_model_id = ""
 
18
 
19
  def generate_text_to_image(
20
  prompt,
21
+ neg_prompt,
 
 
 
 
 
 
 
 
22
  ) -> Any:
23
+ global previous_height, previous_width, previous_model_id, previous_num_of_images, app_settings
24
+ app_settings.settings.lcm_diffusion_setting.prompt = prompt
25
+ app_settings.settings.lcm_diffusion_setting.negative_prompt = neg_prompt
26
+ app_settings.settings.lcm_diffusion_setting.diffusion_task = (
27
+ DiffusionTask.text_to_image.value
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  )
29
+ model_id = app_settings.settings.lcm_diffusion_setting.openvino_lcm_model_id
30
  reshape = False
31
+ image_width = app_settings.settings.lcm_diffusion_setting.image_width
32
+ image_height = app_settings.settings.lcm_diffusion_setting.image_height
33
+ num_images = app_settings.settings.lcm_diffusion_setting.number_of_images
34
+ if app_settings.settings.lcm_diffusion_setting.use_openvino:
35
  reshape = is_reshape_required(
36
  previous_width,
37
  image_width,
 
42
  previous_num_of_images,
43
  num_images,
44
  )
45
+
46
+ with ThreadPoolExecutor(max_workers=1) as executor:
47
+ future = executor.submit(
48
+ context.generate_text_to_image,
49
+ app_settings.settings,
50
+ reshape,
51
+ DEVICE,
52
+ )
53
+ images = future.result()
54
+ # images = context.generate_text_to_image(
55
+ # app_settings.settings,
56
+ # reshape,
57
+ # DEVICE,
58
+ # )
59
  previous_width = image_width
60
  previous_height = image_height
61
  previous_model_id = model_id
62
  previous_num_of_images = num_images
 
63
  return images
64
 
65
 
66
+ def get_text_to_image_ui() -> None:
67
  with gr.Blocks():
68
  with gr.Row():
69
  with gr.Column():
 
 
 
 
 
 
 
 
 
 
 
70
  with gr.Row():
71
  prompt = gr.Textbox(
72
+ show_label=False,
73
  lines=3,
74
  placeholder="A fantasy landscape",
75
+ container=False,
76
  )
77
 
78
  generate_btn = gr.Button(
 
80
  elem_id="generate_button",
81
  scale=0,
82
  )
83
+ negative_prompt = gr.Textbox(
84
+ label="Negative prompt (Works in LCM-LoRA mode, set guidance > 1.0) :",
85
+ lines=1,
86
+ placeholder="",
 
 
 
 
 
 
 
 
 
 
 
87
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
+ input_params = [prompt, negative_prompt]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
  with gr.Column():
92
  output = gr.Gallery(
 
94
  show_label=True,
95
  elem_id="gallery",
96
  columns=2,
97
+ height=512,
98
  )
 
 
99
  generate_btn.click(
100
  fn=generate_text_to_image,
101
  inputs=input_params,
frontend/webui/ui.py CHANGED
@@ -1,8 +1,14 @@
1
  import gradio as gr
2
  from constants import APP_VERSION
3
  from frontend.webui.text_to_image_ui import get_text_to_image_ui
 
 
 
 
4
  from paths import FastStableDiffusionPaths
5
- from app_settings import AppSettings
 
 
6
 
7
 
8
  def _get_footer_message() -> str:
@@ -14,23 +20,54 @@ def _get_footer_message() -> str:
14
  return footer_msg
15
 
16
 
17
- def get_web_ui(app_settings: AppSettings) -> gr.Blocks:
 
 
 
 
 
 
 
 
 
18
  with gr.Blocks(
19
  css=FastStableDiffusionPaths.get_css_path(),
20
  title="FastSD CPU",
21
  ) as fastsd_web_ui:
22
  gr.HTML("<center><H1>FastSD CPU</H1></center>")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  with gr.Tabs():
24
  with gr.TabItem("Text to Image"):
25
- get_text_to_image_ui(app_settings)
 
 
 
 
 
 
 
 
 
26
  gr.HTML(_get_footer_message())
27
 
28
  return fastsd_web_ui
29
 
30
 
31
  def start_webui(
32
- app_settings: AppSettings,
33
  share: bool = False,
34
  ):
35
- webui = get_web_ui(app_settings)
36
  webui.launch(share=share)
 
1
  import gradio as gr
2
  from constants import APP_VERSION
3
  from frontend.webui.text_to_image_ui import get_text_to_image_ui
4
+ from frontend.webui.image_to_image_ui import get_image_to_image_ui
5
+ from frontend.webui.generation_settings_ui import get_generation_settings_ui
6
+ from frontend.webui.models_ui import get_models_ui
7
+ from frontend.webui.image_variations_ui import get_image_variations_ui
8
  from paths import FastStableDiffusionPaths
9
+ from state import get_settings
10
+
11
+ app_settings = get_settings()
12
 
13
 
14
  def _get_footer_message() -> str:
 
20
  return footer_msg
21
 
22
 
23
+ def get_web_ui() -> gr.Blocks:
24
+ def change_mode(mode):
25
+ global app_settings
26
+ app_settings.settings.lcm_diffusion_setting.use_lcm_lora = False
27
+ app_settings.settings.lcm_diffusion_setting.use_openvino = False
28
+ if mode == "LCM-LoRA":
29
+ app_settings.settings.lcm_diffusion_setting.use_lcm_lora = True
30
+ elif mode == "LCM-OpenVINO":
31
+ app_settings.settings.lcm_diffusion_setting.use_openvino = True
32
+
33
  with gr.Blocks(
34
  css=FastStableDiffusionPaths.get_css_path(),
35
  title="FastSD CPU",
36
  ) as fastsd_web_ui:
37
  gr.HTML("<center><H1>FastSD CPU</H1></center>")
38
+ current_mode = "LCM"
39
+ if app_settings.settings.lcm_diffusion_setting.use_openvino:
40
+ current_mode = "LCM-OpenVINO"
41
+ elif app_settings.settings.lcm_diffusion_setting.use_lcm_lora:
42
+ current_mode = "LCM-LoRA"
43
+
44
+ mode = gr.Radio(
45
+ ["LCM", "LCM-LoRA", "LCM-OpenVINO"],
46
+ label="Mode",
47
+ info="Current working mode",
48
+ value=current_mode,
49
+ )
50
+ mode.change(change_mode, inputs=mode)
51
+
52
  with gr.Tabs():
53
  with gr.TabItem("Text to Image"):
54
+ get_text_to_image_ui()
55
+ with gr.TabItem("Image to Image"):
56
+ get_image_to_image_ui()
57
+ with gr.TabItem("Image Variations"):
58
+ get_image_variations_ui()
59
+ with gr.TabItem("Generation Settings"):
60
+ get_generation_settings_ui()
61
+ with gr.TabItem("Models"):
62
+ get_models_ui()
63
+
64
  gr.HTML(_get_footer_message())
65
 
66
  return fastsd_web_ui
67
 
68
 
69
  def start_webui(
 
70
  share: bool = False,
71
  ):
72
+ webui = get_web_ui()
73
  webui.launch(share=share)
paths.py CHANGED
@@ -55,3 +55,7 @@ class FastStableDiffusionPaths:
55
  model_config_file,
56
  )
57
  return models_path
 
 
 
 
 
55
  model_config_file,
56
  )
57
  return models_path
58
+
59
+
60
+ def get_base_folder_name(path: str) -> str:
61
+ return os.path.basename(path)