Vanisper commited on
Commit
ee38d7b
·
1 Parent(s): 0c4f745

chore: 实现多权重模型的叠加效果,允许选择多个权重模型

Browse files
Files changed (2) hide show
  1. app-v2.py +438 -0
  2. app.py +177 -244
app-v2.py ADDED
@@ -0,0 +1,438 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import os
4
+ from utils import call
5
+ from diffusers import (
6
+ DDPMScheduler,
7
+ DDIMScheduler,
8
+ PNDMScheduler,
9
+ LMSDiscreteScheduler,
10
+ EulerAncestralDiscreteScheduler,
11
+ EulerDiscreteScheduler,
12
+ DPMSolverMultistepScheduler,
13
+ )
14
+ from diffusers.pipelines import StableDiffusionXLPipeline
15
+ StableDiffusionXLPipeline.__call__ = call
16
+ import os
17
+ from trainscripts.textsliders.lora import LoRANetwork, DEFAULT_TARGET_REPLACE, UNET_TARGET_REPLACE_MODULE_CONV
18
+ from trainscripts.textsliders.demotrain import train_xl
19
+
20
+ os.environ['CURL_CA_BUNDLE'] = ''
21
+
22
+ model_map = {
23
+ '年龄调整': 'models/age.pt',
24
+ '体型丰满': 'models/chubby.pt',
25
+ '肌肉感': 'models/muscular.pt',
26
+ '惊讶表情': 'models/suprised_look.pt',
27
+ '微笑': 'models/smiling.pt',
28
+ '职业感': 'models/professional.pt',
29
+ '长发': 'models/long_hair.pt',
30
+ '卷发': 'models/curlyhair.pt',
31
+ 'Pixar风格': 'models/pixar_style.pt',
32
+ '雕塑风格': 'models/sculpture_style.pt',
33
+ '陶土风格': 'models/clay_style.pt',
34
+ '修复图像': 'models/repair_slider.pt',
35
+ '修复手部': 'models/fix_hands.pt',
36
+ '杂乱房间': 'models/cluttered_room.pt',
37
+ '阴暗天气': 'models/dark_weather.pt',
38
+ '节日氛围': 'models/festive.pt',
39
+ '热带天气': 'models/tropical_weather.pt',
40
+ '冬季天气': 'models/winter_weather.pt',
41
+ '弯眉': 'models/eyebrow.pt',
42
+ '眼睛大小 (使用刻度 -3, -1, 1, 3)': 'models/eyesize.pt',
43
+ }
44
+
45
+ ORIGINAL_SPACE_ID = 'baulab/ConceptSliders'
46
+ SPACE_ID = os.getenv('SPACE_ID')
47
+
48
+ SHARED_UI_WARNING = f'''## 注意 - 在此共享UI中训练可能会很慢。您可以选择复制并使用至少40GB GPU的设备,或克隆此存储库以在自己的机器上运行。
49
+ <center><a class="duplicate-button" style="display:inline-block" target="_blank" href="https://huggingface.co/spaces/{SPACE_ID}?duplicate=true"><img style="margin-top:0;margin-bottom:0" src="https://img.shields.io/badge/-复制空间-blue?labelColor=white&style=flat&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAP5JREFUOE+lk7FqAkEURY+ltunEgFXS2sZGIbXfEPdLlnxJyDdYB62sbbUKpLbVNhyYFzbrrA74YJlh9r079973psed0cvUD4A+4HoCjsA85X0Dfn/RBLBgBDxnQPfAEJgBY+A9gALA4tcbamSzS4xq4FOQAJgCDwV2CPKV8tZAJcAjMMkUe1vX+U+SMhfAJEHasQIWmXNN3abzDwHUrgcRGmYcgKe0bxrblHEB4E/pndMazNpSZGcsZdBlYJcEL9Afo75molJyM2FxmPgmgPqlWNLGfwZGG6UiyEvLzHYDmoPkDDiNm9JR9uboiONcBXrpY1qmgs21x1QwyZcpvxt9NS09PlsPAAAAAElFTkSuQmCC&logoWidth=14" alt="复制空间"></a></center>
50
+ '''
51
+
52
+ def merge_lora_networks(networks):
53
+ if not networks:
54
+ return None
55
+
56
+ base_network = networks[0]
57
+ for network in networks[1:]:
58
+ for name, param in network.named_parameters():
59
+ if name in base_network.state_dict():
60
+ base_network.state_dict()[name].add_(param)
61
+ else:
62
+ base_network.state_dict()[name] = param.clone()
63
+ return base_network
64
+
65
+ # 修改 call 方法以支持传递 networks 参数
66
+ # def rw_sd_call(self, *args, networks=None, scales=None, **kwargs):
67
+ # if networks is not None and scales is not None:
68
+ # for network, scale in zip(networks, scales):
69
+ # for name, param in network.named_parameters():
70
+ # if name in self.unet.state_dict():
71
+ # self.unet.state_dict()[name].add_(param * scale)
72
+ # else:
73
+ # self.unet.state_dict()[name] = param.clone() * scale
74
+ # return self.__original_call__(*args, **kwargs)
75
+
76
+ # StableDiffusionXLPipeline.__original_call__ = StableDiffusionXLPipeline.__call__
77
+ # StableDiffusionXLPipeline.__call__ = rw_sd_call
78
+
79
+ class Demo:
80
+
81
+ def __init__(self) -> None:
82
+
83
+ self.training = False
84
+ self.generating = False
85
+ self.weight_dtype = torch.bfloat16
86
+ self.model_sections = []
87
+
88
+ model_id = 'stabilityai/stable-diffusion-xl-base-1.0'
89
+ if torch.cuda.is_available():
90
+ self.device = 'cuda'
91
+ else:
92
+ self.device = 'cpu'
93
+
94
+ pipe = StableDiffusionXLPipeline.from_pretrained(model_id, torch_dtype=self.weight_dtype).to(self.device)
95
+ pipe = None
96
+ del pipe
97
+ torch.cuda.empty_cache()
98
+
99
+ model_id = "stabilityai/sdxl-turbo"
100
+ self.current_model = 'SDXL Turbo'
101
+ euler_anc = EulerAncestralDiscreteScheduler.from_pretrained(model_id, subfolder="scheduler")
102
+ self.pipe = StableDiffusionXLPipeline.from_pretrained(model_id, scheduler=euler_anc, torch_dtype=self.weight_dtype).to(self.device)
103
+ if torch.cuda.is_available():
104
+ self.pipe.enable_xformers_memory_efficient_attention()
105
+
106
+ self.guidance_scale = 1
107
+ self.num_inference_steps = 3
108
+ self.seed = 42753 # 默认种子值
109
+
110
+ with gr.Blocks() as demo:
111
+ self.layout()
112
+ demo.queue(max_size=5).launch(share=True, max_threads=2)
113
+
114
+
115
+ def layout(self):
116
+ # with gr.Row():
117
+
118
+ # if SPACE_ID == ORIGINAL_SPACE_ID:
119
+
120
+ # self.warning = gr.Markdown(SHARED_UI_WARNING)
121
+
122
+ # with gr.Row():
123
+
124
+ with gr.Tab("测试") as inference_column:
125
+
126
+ with gr.Row():
127
+
128
+ self.explain_infr = gr.Markdown(value='这是[概念滑块:用于扩散模型的LoRA适配器](https://sliders.baulab.info/)的演示。要尝试可以控制特定概念的模型,请选择一个模型并输入任何提示词,选择一个种子值,最后选择SDEdit时间步以保持结构。较高的SDEdit时间步会导致更多的结构变化。例如,如果选择“惊讶表情”模型,可以生成提示词“A picture of a person, realistic, 8k”的图像,并将滑块效果与原始模型生成的图像进行比较。我们还提供了几个其他预先微调的模型,如“修复”滑块,用于修复SDXL生成图像中的缺陷(请查看“预训练滑块”下拉菜单)。您还可以训练和运行自己的自定义滑块。请查看“训练”部分以进行自定义概念滑块训练。<b>当前推理正在运行SDXL Turbo!</b>')
129
+
130
+ with gr.Row():
131
+
132
+ self.prompt_input_infr = gr.Text(
133
+ placeholder="photo of a person, with bokeh street background, realistic, 8k",
134
+ label="提示词",
135
+ info="生成图像的提示词",
136
+ value="photo of a person, with bokeh street background, realistic, 8k"
137
+ )
138
+
139
+ for model_name in model_map.keys():
140
+ with gr.Row():
141
+ model_checkbox = gr.Checkbox(label=model_name, value=False)
142
+ slider_scale_infr = gr.Slider(-4, 4, label="滑块刻度", value=3, info="较大的滑块刻度会导致更强的编辑效果")
143
+ self.model_sections.append(((model_checkbox.label, model_checkbox.value), slider_scale_infr.value))
144
+
145
+ # 添加复选框的change事件处理程序
146
+ model_checkbox.change(
147
+ fn=self.update_model_sections,
148
+ inputs=[gr.Text(value=f"{model_checkbox.label}"), model_checkbox, slider_scale_infr],
149
+ outputs=[]
150
+ )
151
+
152
+ with gr.Row():
153
+ self.seed_infr = gr.Number(label="种子值", value=self.seed)
154
+ self.start_noise_infr = gr.Slider(
155
+ 600, 900,
156
+ value=750,
157
+ label="SDEdit时间步",
158
+ info="选择较小的值以保持更多结构"
159
+ )
160
+ self.model_type = gr.Dropdown(
161
+ label="模型",
162
+ choices=['SDXL Turbo', 'SDXL'],
163
+ value='SDXL Turbo',
164
+ interactive=True
165
+ )
166
+
167
+ with gr.Row():
168
+ self.infr_button = gr.Button(
169
+ value="生成",
170
+ interactive=True
171
+ )
172
+
173
+ with gr.Row():
174
+ self.image_orig = gr.Image(
175
+ label="原始SD",
176
+ interactive=False,
177
+ type='pil',
178
+ )
179
+
180
+ self.image_new = gr.Image(
181
+ label=f"概念滑块",
182
+ interactive=False,
183
+ type='pil',
184
+ )
185
+
186
+ with gr.Tab("训练") as training_column:
187
+
188
+ with gr.Row():
189
+
190
+ self.explain_train= gr.Markdown(value='在这一部分,您可以为Stable Diffusion XL训练文本概念滑块。输入您希望进行编辑的目标概念(例如:人)。接下来,输入您希望编辑的属性的增强提示词(例如:控制人的年龄,输入“person, old”)。然后,输入属性的抑制提示词(例如:输入“person, young”)。然后按“训练”按钮。使用默认设置,训练一个滑块大约需要25分钟;然后您可以在上面的“测试”选项卡中尝试推理或下载权重。为了更快的训练,请复制此存储库并使用A100或更大的GPU进行训练。代码和详细信息在[github链接](https://github.com/rohitgandikota/sliders)。')
191
+
192
+ with gr.Row():
193
+
194
+ with gr.Column(scale=3):
195
+
196
+ self.target_concept = gr.Text(
197
+ placeholder="输入要进行编辑的目标概念...",
198
+ label="编辑概念的提示词",
199
+ info="对应于要编辑的概念的提示词(例如:“person”)",
200
+ value = ''
201
+ )
202
+
203
+ self.positive_prompt = gr.Text(
204
+ placeholder="输入编辑的增强提示词...",
205
+ label="增强���示词",
206
+ info="对应于要增强的概念的提示词(例如:“person, old”)",
207
+ value = ''
208
+ )
209
+
210
+ self.negative_prompt = gr.Text(
211
+ placeholder="输入编辑的抑制提示词...",
212
+ label="抑制提示词",
213
+ info="对应于要抑制的概念的提示词(例如:“person, young”)",
214
+ value = ''
215
+ )
216
+
217
+ self.attributes_input = gr.Text(
218
+ placeholder="输入要保留的概念(用逗号分隔)。如果不需要,请留空...",
219
+ label="要保留的概念",
220
+ info="要保留/解缠的概念(例如:“male, female”)",
221
+ value = ''
222
+ )
223
+ self.is_person = gr.Checkbox(
224
+ label="人",
225
+ info="您是否在为人训练滑块?")
226
+
227
+ self.rank = gr.Number(
228
+ value=4,
229
+ label="滑块等级",
230
+ info='要训练的滑块等级'
231
+ )
232
+ choices = ['xattn', 'noxattn']
233
+ self.train_method_input = gr.Dropdown(
234
+ choices=choices,
235
+ value='xattn',
236
+ label='训练方法',
237
+ info='训练方法。如果[* xattn *] - loras将仅在交叉注意层上。如果[* noxattn *](官方实现) - 除交叉注意层外的所有层',
238
+ interactive=True
239
+ )
240
+ self.iterations_input = gr.Number(
241
+ value=500,
242
+ precision=0,
243
+ label="迭代次数",
244
+ info='用于训练的迭代次数 - 最大为1000'
245
+ )
246
+
247
+ self.lr_input = gr.Number(
248
+ value=2e-4,
249
+ label="学习率",
250
+ info='用于训练的学习率'
251
+ )
252
+
253
+ with gr.Column(scale=1):
254
+
255
+ self.train_status = gr.Button(value='', variant='primary', interactive=False)
256
+
257
+ self.train_button = gr.Button(
258
+ value="训练",
259
+ )
260
+
261
+ self.download = gr.Files()
262
+ self.model_dropdown = gr.Dropdown(choices=list(model_map.keys()))
263
+
264
+ self.infr_button.click(self.inference, inputs=[
265
+ self.prompt_input_infr,
266
+ self.start_noise_infr,
267
+ self.model_type,
268
+ self.seed_infr
269
+ ],
270
+ outputs=[
271
+ self.image_new,
272
+ self.image_orig
273
+ ]
274
+ )
275
+ self.train_button.click(self.train, inputs = [
276
+ self.target_concept,
277
+ self.positive_prompt,
278
+ self.negative_prompt,
279
+ self.rank,
280
+ self.iterations_input,
281
+ self.lr_input,
282
+ self.attributes_input,
283
+ self.is_person,
284
+ self.train_method_input
285
+ ],
286
+ outputs=[self.train_button, self.train_status, self.download, self.model_dropdown]
287
+ )
288
+
289
+ def update_model_sections(self, label, checkbox, scale):
290
+ for i, section in enumerate(self.model_sections):
291
+ if section[0][0] == label:
292
+ self.model_sections[i] = ((label, checkbox), scale)
293
+ break
294
+
295
+ def train(self, target_concept,positive_prompt, negative_prompt, rank, iterations_input, lr_input, attributes_input, is_person, train_method_input, pbar = gr.Progress(track_tqdm=True)):
296
+ iterations_input = min(int(iterations_input),1000)
297
+ if attributes_input == '':
298
+ attributes_input = None
299
+ print(target_concept, positive_prompt, negative_prompt, attributes_input, is_person)
300
+
301
+ randn = torch.randint(1, 10000000, (1,)).item()
302
+ save_name = f"{randn}_{positive_prompt.replace(',','').replace(' ','').replace('.','')[:20]}"
303
+ save_name += f'_alpha-{1}'
304
+ save_name += f'_{train_method_input}'
305
+ save_name += f'_rank_{int(rank)}.pt'
306
+
307
+ # if torch.cuda.get_device_properties(0).total_memory * 1e-9 < 40:
308
+ # return [gr.update(interactive=True, value='Train'), gr.update(value='GPU Memory is not enough for training... Please upgrade to GPU atleast 40GB or clone the repo to your local machine.'), None, gr.update()]
309
+ if self.training:
310
+ return [gr.update(interactive=True, value='Train'), gr.update(value='Someone else is training... Try again soon'), None, gr.update()]
311
+
312
+ attributes = attributes_input
313
+ if is_person:
314
+ attributes = 'white, black, asian, hispanic, indian, male, female'
315
+
316
+ self.training = True
317
+ train_xl(target=target_concept, positive=positive_prompt, negative=negative_prompt, lr=lr_input, iterations=iterations_input, config_file='trainscripts/textsliders/data/config-xl.yaml', rank=int(rank), train_method=train_method_input, device=self.device, attributes=attributes, save_name=save_name)
318
+ self.training = False
319
+
320
+ torch.cuda.empty_cache()
321
+ model_map[save_name.replace('.pt','')] = f'models/{save_name}'
322
+
323
+ return [gr.update(interactive=True, value='Train'), gr.update(value='Done Training! \n Try your custom slider in the "Test" tab'), f'models/{save_name}', gr.update(choices=list(model_map.keys()), value=save_name.replace('.pt',''))]
324
+
325
+ def get_selected_models(self):
326
+ # 过滤出被选中的模型数据
327
+ selected = [
328
+ (section[0][0], section[1]) # (label, scale)
329
+ for section in self.model_sections
330
+ if section[0][1] # 检查 checkbox value 是否为 True
331
+ ]
332
+
333
+ if selected:
334
+ # 解包成两个数组
335
+ labels, scales = zip(*selected)
336
+ return list(labels), list(scales)
337
+ else:
338
+ return [], []
339
+
340
+ def inference(self, prompt, start_noise, model, seed, pbar=gr.Progress(track_tqdm=True)):
341
+ self.seed = seed # 更新种子值
342
+ result = self.get_selected_models()
343
+ print(111, self.model_sections)
344
+ model_names, scale_list = result
345
+ print(222, model_names, scale_list)
346
+
347
+ if self.current_model != model:
348
+ if model=='SDXL Turbo':
349
+ model_id = "stabilityai/sdxl-turbo"
350
+ euler_anc = EulerAncestralDiscreteScheduler.from_pretrained(model_id, subfolder="scheduler")
351
+ self.pipe = StableDiffusionXLPipeline.from_pretrained(model_id, scheduler=euler_anc, torch_dtype=self.weight_dtype).to(self.device)
352
+ if torch.cuda.is_available():
353
+ self.pipe.enable_xformers_memory_efficient_attention()
354
+ self.guidance_scale = 1
355
+ self.num_inference_steps = 3
356
+ self.current_model = 'SDXL Turbo'
357
+ else:
358
+ model_id = 'stabilityai/stable-diffusion-xl-base-1.0'
359
+ self.pipe = StableDiffusionXLPipeline.from_pretrained(model_id, torch_dtype=self.weight_dtype).to(self.device)
360
+ if torch.cuda.is_available():
361
+ self.pipe.enable_xformers_memory_efficient_attention()
362
+ self.guidance_scale = 7.5
363
+ self.num_inference_steps = 20
364
+ self.current_model = 'SDXL'
365
+
366
+ networks = []
367
+ for model_name in model_names:
368
+ model_path = model_map[model_name]
369
+ unet = self.pipe.unet
370
+ network_type = "c3lier"
371
+ if 'full' in model_path:
372
+ train_method = 'full'
373
+ elif 'noxattn' in model_path:
374
+ train_method = 'noxattn'
375
+ elif 'xattn' in model_path:
376
+ train_method = 'xattn'
377
+ network_type = 'lierla'
378
+ else:
379
+ train_method = 'noxattn'
380
+
381
+ modules = DEFAULT_TARGET_REPLACE
382
+ if network_type == "c3lier":
383
+ modules += UNET_TARGET_REPLACE_MODULE_CONV
384
+
385
+ name = os.path.basename(model_path)
386
+ rank = 4
387
+ alpha = 1
388
+ if 'rank' in model_path:
389
+ rank = int(float(model_path.split('_')[-1].replace('.pt','')))
390
+ if 'alpha1' in model_path:
391
+ alpha = 1.0
392
+ network = LoRANetwork(
393
+ unet,
394
+ rank=rank,
395
+ multiplier=1.0,
396
+ alpha=alpha,
397
+ train_method=train_method,
398
+ ).to(self.device, dtype=self.weight_dtype)
399
+ network.load_state_dict(torch.load(model_path, weights_only=True))
400
+ networks.append(network)
401
+
402
+ # 设置种子
403
+ generator = torch.manual_seed(self.seed)
404
+ # 生成编辑后的图像(应用多权重)
405
+ edited_image = self.pipe(
406
+ prompt,
407
+ num_images_per_prompt=1,
408
+ num_inference_steps=self.num_inference_steps,
409
+ generator=generator,
410
+ networks=networks, # 加载多个 LoRA 模型
411
+ start_noise=int(start_noise),
412
+ scales=scale_list, # 设置每个 LoRA 的权重
413
+ unet=unet,
414
+ guidance_scale=self.guidance_scale
415
+ ).images[0]
416
+
417
+ # 生成原始图像(不应用权重)
418
+ generator = torch.manual_seed(self.seed)
419
+ original_image = self.pipe(
420
+ prompt,
421
+ num_images_per_prompt=1,
422
+ num_inference_steps=self.num_inference_steps,
423
+ generator=generator,
424
+ networks=networks,
425
+ start_noise=int(start_noise),
426
+ scales=[0] * len(networks), # 不设置任何权重
427
+ unet=unet,
428
+ guidance_scale=self.guidance_scale
429
+ ).images[0]
430
+
431
+ del unet, networks
432
+ unet = None
433
+ networks = None
434
+ torch.cuda.empty_cache()
435
+
436
+ return edited_image, original_image
437
+
438
+ demo = Demo()
app.py CHANGED
@@ -49,32 +49,6 @@ SHARED_UI_WARNING = f'''## 注意 - 在此共享UI中训练可能会很慢。您
49
  <center><a class="duplicate-button" style="display:inline-block" target="_blank" href="https://huggingface.co/spaces/{SPACE_ID}?duplicate=true"><img style="margin-top:0;margin-bottom:0" src="https://img.shields.io/badge/-复制空间-blue?labelColor=white&style=flat&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAP5JREFUOE+lk7FqAkEURY+ltunEgFXS2sZGIbXfEPdLlnxJyDdYB62sbbUKpLbVNhyYFzbrrA74YJlh9r079973psed0cvUD4A+4HoCjsA85X0Dfn/RBLBgBDxnQPfAEJgBY+A9gALA4tcbamSzS4xq4FOQAJgCDwV2CPKV8tZAJcAjMMkUe1vX+U+SMhfAJEHasQIWmXNN3abzDwHUrgcRGmYcgKe0bxrblHEB4E/pndMazNpSZGcsZdBlYJcEL9Afo75molJyM2FxmPgmgPqlWNLGfwZGG6UiyEvLzHYDmoPkDDiNm9JR9uboiONcBXrpY1qmgs21x1QwyZcpvxt9NS09PlsPAAAAAElFTkSuQmCC&logoWidth=14" alt="复制空间"></a></center>
50
  '''
51
 
52
- def merge_lora_networks(networks):
53
- if not networks:
54
- return None
55
-
56
- base_network = networks[0]
57
- for network in networks[1:]:
58
- for name, param in network.named_parameters():
59
- if name in base_network.state_dict():
60
- base_network.state_dict()[name].add_(param)
61
- else:
62
- base_network.state_dict()[name] = param.clone()
63
- return base_network
64
-
65
- # 修改 call 方法以支持传递 networks 参数
66
- # def rw_sd_call(self, *args, networks=None, scales=None, **kwargs):
67
- # if networks is not None and scales is not None:
68
- # for network, scale in zip(networks, scales):
69
- # for name, param in network.named_parameters():
70
- # if name in self.unet.state_dict():
71
- # self.unet.state_dict()[name].add_(param * scale)
72
- # else:
73
- # self.unet.state_dict()[name] = param.clone() * scale
74
- # return self.__original_call__(*args, **kwargs)
75
-
76
- # StableDiffusionXLPipeline.__original_call__ = StableDiffusionXLPipeline.__call__
77
- # StableDiffusionXLPipeline.__call__ = rw_sd_call
78
 
79
  class Demo:
80
 
@@ -82,15 +56,10 @@ class Demo:
82
 
83
  self.training = False
84
  self.generating = False
 
85
  self.weight_dtype = torch.bfloat16
86
- self.model_sections = []
87
 
88
  model_id = 'stabilityai/stable-diffusion-xl-base-1.0'
89
- if torch.cuda.is_available():
90
- self.device = 'cuda'
91
- else:
92
- self.device = 'cpu'
93
-
94
  pipe = StableDiffusionXLPipeline.from_pretrained(model_id, torch_dtype=self.weight_dtype).to(self.device)
95
  pipe = None
96
  del pipe
@@ -100,12 +69,10 @@ class Demo:
100
  self.current_model = 'SDXL Turbo'
101
  euler_anc = EulerAncestralDiscreteScheduler.from_pretrained(model_id, subfolder="scheduler")
102
  self.pipe = StableDiffusionXLPipeline.from_pretrained(model_id, scheduler=euler_anc, torch_dtype=self.weight_dtype).to(self.device)
103
- if torch.cuda.is_available():
104
- self.pipe.enable_xformers_memory_efficient_attention()
105
 
106
  self.guidance_scale = 1
107
  self.num_inference_steps = 3
108
- self.seed = 42753 # 默认种子值
109
 
110
  with gr.Blocks() as demo:
111
  self.layout()
@@ -113,159 +80,173 @@ class Demo:
113
 
114
 
115
  def layout(self):
116
- # with gr.Row():
117
 
118
- # if SPACE_ID == ORIGINAL_SPACE_ID:
 
 
119
 
120
- # self.warning = gr.Markdown(SHARED_UI_WARNING)
121
 
122
- # with gr.Row():
123
 
124
- with gr.Tab("测试") as inference_column:
125
 
126
- with gr.Row():
127
 
128
- self.explain_infr = gr.Markdown(value='这是[概念滑块:用于扩散模型的LoRA适配器](https://sliders.baulab.info/)的演示。要尝试可以控制特定概念的模型,请选择一个模型并输入任何提示词,选择一个种子值,最后选择SDEdit时间步以保持结构。较高的SDEdit时间步会导致更多的结构变化。例如,如果选择“惊讶表情”模型,可以生成提示词“A picture of a person, realistic, 8k”的图像,并将滑块效果与原始模型生成的图像进行比较。我们还提供了几个其他预先微调的模型,如“修复”滑块,用于修复SDXL生成图像中的缺陷(请查看“预训练滑块”下拉菜单)。您还可以训练和运行自己的自定义滑块。请查看“训练”部分以进行自定义概念滑块训练。<b>当前推理正在运行SDXL Turbo!</b>')
129
 
130
- with gr.Row():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
 
132
- self.prompt_input_infr = gr.Text(
133
- placeholder="photo of a person, with bokeh street background, realistic, 8k",
134
- label="提示词",
135
- info="生成图像的提示词",
136
- value="photo of a person, with bokeh street background, realistic, 8k"
137
- )
138
-
139
- for model_name in model_map.keys():
140
  with gr.Row():
141
- model_checkbox = gr.Checkbox(label=model_name, value=False)
142
- slider_scale_infr = gr.Slider(-4, 4, label="滑块刻度", value=3, info="较大的滑块刻度会导致更强的编辑效果")
143
- self.model_sections.append(((model_checkbox.label, model_checkbox.value), slider_scale_infr.value))
144
-
145
- # 添加复选框的change事件处理程序
146
- model_checkbox.change(
147
- fn=self.update_model_sections,
148
- inputs=[gr.Text(value=f"{model_checkbox.label}"), model_checkbox, slider_scale_infr],
149
- outputs=[]
150
- )
151
-
152
- with gr.Row():
153
- self.seed_infr = gr.Number(label="种子值", value=self.seed)
154
- self.start_noise_infr = gr.Slider(
155
- 600, 900,
156
- value=750,
157
- label="SDEdit时间步",
158
- info="选择较小的值以保持更多结构"
159
- )
160
- self.model_type = gr.Dropdown(
161
- label="模型",
162
- choices=['SDXL Turbo', 'SDXL'],
163
- value='SDXL Turbo',
164
- interactive=True
165
- )
166
-
167
- with gr.Row():
168
- self.infr_button = gr.Button(
169
- value="生成",
170
- interactive=True
171
- )
172
-
173
- with gr.Row():
174
- self.image_orig = gr.Image(
175
- label="原始SD",
176
- interactive=False,
177
- type='pil',
178
- )
179
-
180
- self.image_new = gr.Image(
181
- label=f"概念滑块",
182
- interactive=False,
183
- type='pil',
184
- )
185
-
186
- with gr.Tab("训练") as training_column:
187
-
188
- with gr.Row():
189
-
190
- self.explain_train= gr.Markdown(value='在这一部分,您可以为Stable Diffusion XL训练文本概念滑块。输入您希望进行编辑的目标概念(例如:人)。接下来,输入您希望编辑的属性的增强提示词(例如:控制人的年龄,输入“person, old”)。然后,输入属性的抑制提示词(例如:输入“person, young”)。然后按“训练”按钮。使用默认设置,训练一个滑块大约需要25分钟;然后您可以在上面的“测试”选项卡中尝试推理或下载权重。为了更快的训练,请复制此存储库并使用A100或更大的GPU进行训练。代码和详细信息在[github链接](https://github.com/rohitgandikota/sliders)。')
191
-
192
- with gr.Row():
193
-
194
- with gr.Column(scale=3):
195
-
196
- self.target_concept = gr.Text(
197
- placeholder="输入要进行编辑的目标概念...",
198
- label="编辑概念的提示词",
199
- info="对应于要编辑的概念的提示词(例如:“person”)",
200
- value = ''
201
- )
202
-
203
- self.positive_prompt = gr.Text(
204
- placeholder="输入编辑的增强提示词...",
205
- label="增强提示词",
206
- info="对应于要增强的概念的提示词(例如:“person, old”)",
207
- value = ''
208
- )
209
-
210
- self.negative_prompt = gr.Text(
211
- placeholder="输入编辑的抑制提示词...",
212
- label="抑制提示词",
213
- info="对应于要抑制的概念的提示词(例如:“person, young”)",
214
- value = ''
215
- )
216
-
217
- self.attributes_input = gr.Text(
218
- placeholder="输入要保留的概念(用逗号分隔)。如果不需要,请留空...",
219
- label="要保留的概念",
220
- info="要保留/解缠的概念(例如:“male, female”)",
221
- value = ''
222
- )
223
- self.is_person = gr.Checkbox(
224
- label="人",
225
- info="您是否在为人训练滑块?")
226
-
227
- self.rank = gr.Number(
228
- value=4,
229
- label="滑块等级",
230
- info='要训练的滑块等级'
231
- )
232
- choices = ['xattn', 'noxattn']
233
- self.train_method_input = gr.Dropdown(
234
- choices=choices,
235
- value='xattn',
236
- label='训练方法',
237
- info='训练方法。如果[* xattn *] - loras将仅在交叉注意层上。如果[* noxattn *](官方实现) - 除交叉注意层外的所有层',
238
- interactive=True
239
- )
240
- self.iterations_input = gr.Number(
241
- value=500,
242
- precision=0,
243
- label="迭代次数",
244
- info='用于训练的迭代次数 - 最大为1000'
245
- )
246
-
247
- self.lr_input = gr.Number(
248
- value=2e-4,
249
- label="学习率",
250
- info='用于训练的学习率'
251
- )
252
-
253
- with gr.Column(scale=1):
254
-
255
- self.train_status = gr.Button(value='', variant='primary', interactive=False)
256
-
257
- self.train_button = gr.Button(
258
- value="训练",
259
- )
260
-
261
- self.download = gr.Files()
262
- self.model_dropdown = gr.Dropdown(choices=list(model_map.keys()))
263
-
264
- self.infr_button.click(self.inference, inputs=[
265
  self.prompt_input_infr,
 
266
  self.start_noise_infr,
267
- self.model_type,
268
- self.seed_infr
 
269
  ],
270
  outputs=[
271
  self.image_new,
@@ -286,12 +267,6 @@ class Demo:
286
  outputs=[self.train_button, self.train_status, self.download, self.model_dropdown]
287
  )
288
 
289
- def update_model_sections(self, label, checkbox, scale):
290
- for i, section in enumerate(self.model_sections):
291
- if section[0][0] == label:
292
- self.model_sections[i] = ((label, checkbox), scale)
293
- break
294
-
295
  def train(self, target_concept,positive_prompt, negative_prompt, rank, iterations_input, lr_input, attributes_input, is_person, train_method_input, pbar = gr.Progress(track_tqdm=True)):
296
  iterations_input = min(int(iterations_input),1000)
297
  if attributes_input == '':
@@ -322,47 +297,28 @@ class Demo:
322
 
323
  return [gr.update(interactive=True, value='Train'), gr.update(value='Done Training! \n Try your custom slider in the "Test" tab'), f'models/{save_name}', gr.update(choices=list(model_map.keys()), value=save_name.replace('.pt',''))]
324
 
325
- def get_selected_models(self):
326
- # 过滤出被选中的模型数据
327
- selected = [
328
- (section[0][0], section[1]) # (label, scale)
329
- for section in self.model_sections
330
- if section[0][1] # 检查 checkbox value 是否为 True
331
- ]
332
-
333
- if selected:
334
- # 解包成两个数组
335
- labels, scales = zip(*selected)
336
- return list(labels), list(scales)
337
- else:
338
- return [], []
339
 
340
- def inference(self, prompt, start_noise, model, seed, pbar=gr.Progress(track_tqdm=True)):
341
- self.seed = seed # 更新种子值
342
- result = self.get_selected_models()
343
- print(111, self.model_sections)
344
- model_names, scale_list = result
345
- print(222, model_names, scale_list)
346
-
347
  if self.current_model != model:
348
  if model=='SDXL Turbo':
349
  model_id = "stabilityai/sdxl-turbo"
350
  euler_anc = EulerAncestralDiscreteScheduler.from_pretrained(model_id, subfolder="scheduler")
351
  self.pipe = StableDiffusionXLPipeline.from_pretrained(model_id, scheduler=euler_anc, torch_dtype=self.weight_dtype).to(self.device)
352
- if torch.cuda.is_available():
353
- self.pipe.enable_xformers_memory_efficient_attention()
354
  self.guidance_scale = 1
355
  self.num_inference_steps = 3
356
  self.current_model = 'SDXL Turbo'
357
  else:
358
  model_id = 'stabilityai/stable-diffusion-xl-base-1.0'
359
  self.pipe = StableDiffusionXLPipeline.from_pretrained(model_id, torch_dtype=self.weight_dtype).to(self.device)
360
- if torch.cuda.is_available():
361
- self.pipe.enable_xformers_memory_efficient_attention()
362
  self.guidance_scale = 7.5
363
  self.num_inference_steps = 20
364
  self.current_model = 'SDXL'
365
-
 
366
  networks = []
367
  for model_name in model_names:
368
  model_path = model_map[model_name]
@@ -390,43 +346,20 @@ class Demo:
390
  if 'alpha1' in model_path:
391
  alpha = 1.0
392
  network = LoRANetwork(
393
- unet,
394
- rank=rank,
395
- multiplier=1.0,
396
- alpha=alpha,
397
- train_method=train_method,
398
- ).to(self.device, dtype=self.weight_dtype)
399
- network.load_state_dict(torch.load(model_path, weights_only=True))
400
  networks.append(network)
401
 
402
- # 设置种子
403
- generator = torch.manual_seed(self.seed)
404
- # 生成编辑后的图像(应用多权重)
405
- edited_image = self.pipe(
406
- prompt,
407
- num_images_per_prompt=1,
408
- num_inference_steps=self.num_inference_steps,
409
- generator=generator,
410
- networks=networks, # 加载多个 LoRA 模型
411
- start_noise=int(start_noise),
412
- scales=scale_list, # 设置每个 LoRA 的权重
413
- unet=unet,
414
- guidance_scale=self.guidance_scale
415
- ).images[0]
416
-
417
- # 生成原始图像(不应用权重)
418
- generator = torch.manual_seed(self.seed)
419
- original_image = self.pipe(
420
- prompt,
421
- num_images_per_prompt=1,
422
- num_inference_steps=self.num_inference_steps,
423
- generator=generator,
424
- networks=networks,
425
- start_noise=int(start_noise),
426
- scales=[0] * len(networks), # 不设置任何权重
427
- unet=unet,
428
- guidance_scale=self.guidance_scale
429
- ).images[0]
430
 
431
  del unet, networks
432
  unet = None
 
49
  <center><a class="duplicate-button" style="display:inline-block" target="_blank" href="https://huggingface.co/spaces/{SPACE_ID}?duplicate=true"><img style="margin-top:0;margin-bottom:0" src="https://img.shields.io/badge/-复制空间-blue?labelColor=white&style=flat&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAP5JREFUOE+lk7FqAkEURY+ltunEgFXS2sZGIbXfEPdLlnxJyDdYB62sbbUKpLbVNhyYFzbrrA74YJlh9r079973psed0cvUD4A+4HoCjsA85X0Dfn/RBLBgBDxnQPfAEJgBY+A9gALA4tcbamSzS4xq4FOQAJgCDwV2CPKV8tZAJcAjMMkUe1vX+U+SMhfAJEHasQIWmXNN3abzDwHUrgcRGmYcgKe0bxrblHEB4E/pndMazNpSZGcsZdBlYJcEL9Afo75molJyM2FxmPgmgPqlWNLGfwZGG6UiyEvLzHYDmoPkDDiNm9JR9uboiONcBXrpY1qmgs21x1QwyZcpvxt9NS09PlsPAAAAAElFTkSuQmCC&logoWidth=14" alt="复制空间"></a></center>
50
  '''
51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
  class Demo:
54
 
 
56
 
57
  self.training = False
58
  self.generating = False
59
+ self.device = 'cuda'
60
  self.weight_dtype = torch.bfloat16
 
61
 
62
  model_id = 'stabilityai/stable-diffusion-xl-base-1.0'
 
 
 
 
 
63
  pipe = StableDiffusionXLPipeline.from_pretrained(model_id, torch_dtype=self.weight_dtype).to(self.device)
64
  pipe = None
65
  del pipe
 
69
  self.current_model = 'SDXL Turbo'
70
  euler_anc = EulerAncestralDiscreteScheduler.from_pretrained(model_id, subfolder="scheduler")
71
  self.pipe = StableDiffusionXLPipeline.from_pretrained(model_id, scheduler=euler_anc, torch_dtype=self.weight_dtype).to(self.device)
72
+ self.pipe.enable_xformers_memory_efficient_attention()
 
73
 
74
  self.guidance_scale = 1
75
  self.num_inference_steps = 3
 
76
 
77
  with gr.Blocks() as demo:
78
  self.layout()
 
80
 
81
 
82
  def layout(self):
 
83
 
84
+ with gr.Row():
85
+
86
+ if SPACE_ID == ORIGINAL_SPACE_ID:
87
 
88
+ self.warning = gr.Markdown(SHARED_UI_WARNING)
89
 
90
+ with gr.Row():
91
 
92
+ with gr.Tab("测试") as inference_column:
93
 
94
+ with gr.Row():
95
 
96
+ self.explain_infr = gr.Markdown(value='这是[概念滑块:用于扩散模型的LoRA适配器](https://sliders.baulab.info/)的演示。要尝试可以控制特定概念的模型,请选择一个模型并输入任何提示词,选择一个种子值,最后选择SDEdit时间步以保持结构。较高的SDEdit��间步会导致更多的结构变化。例如,如果选择“惊讶表情”模型,可以生成提示词“A picture of a person, realistic, 8k”的图像,并将滑块效果与原始模型生成的图像进行比较。我们还提供了几个其他预先微调的模型,如“修复”滑块,用于修复SDXL生成图像中的缺陷(请查看“预训练滑块”下拉菜单)。您还可以训练和运行自己的自定义滑块。请查看“训练”部分以进行自定义概念滑块训练。<b>当前推理正在运行SDXL Turbo!</b>')
97
 
98
+ with gr.Row():
99
+
100
+ with gr.Column(scale=1):
101
+
102
+ self.prompt_input_infr = gr.Text(
103
+ placeholder="photo of a person, with bokeh street background, realistic, 8k",
104
+ label="提示词",
105
+ info="生成图像的提示词",
106
+ value="photo of a person, with bokeh street background, realistic, 8k"
107
+ )
108
+
109
+ with gr.Row():
110
+
111
+ self.model_dropdown = gr.Dropdown(
112
+ label="预训练滑块",
113
+ choices= list(model_map.keys()),
114
+ value=['年龄调整'],
115
+ interactive=True,
116
+ multiselect=True # 允许多选
117
+ )
118
+
119
+ self.seed_infr = gr.Number(
120
+ label="种子值",
121
+ value=42753
122
+ )
123
+
124
+ self.slider_scale_infr = gr.Slider(
125
+ -4,
126
+ 4,
127
+ label="滑块刻度",
128
+ value=3,
129
+ info="较大的滑块刻度会导致更强的编辑效果"
130
+ )
131
+
132
+
133
+ self.start_noise_infr = gr.Slider(
134
+ 600, 900,
135
+ value=750,
136
+ label="SDEdit时间步",
137
+ info="选择较小的值以保持更多结构"
138
+ )
139
+ self.model_type = gr.Dropdown(
140
+ label="模型",
141
+ choices= ['SDXL Turbo', 'SDXL'],
142
+ value='SDXL Turbo',
143
+ interactive=True
144
+ )
145
+ with gr.Column(scale=2):
146
+
147
+ self.infr_button = gr.Button(
148
+ value="生成",
149
+ interactive=True
150
+ )
151
+
152
+ with gr.Row():
153
+
154
+ self.image_orig = gr.Image(
155
+ label="原始SD",
156
+ interactive=False,
157
+ type='pil',
158
+ )
159
+
160
+ self.image_new = gr.Image(
161
+ label=f"概念滑块",
162
+ interactive=False,
163
+ type='pil',
164
+ )
165
+
166
+ with gr.Tab("训练") as training_column:
167
 
 
 
 
 
 
 
 
 
168
  with gr.Row():
169
+
170
+ self.explain_train= gr.Markdown(value='在这一部分,您可以为Stable Diffusion XL训练文本概念滑块。输入您希望进行编辑的目标概念(例如:人)。接下来,输入您希望编辑的属性的增强提示词(例如:控制人的年龄,输入“person, old”)。然后,输入属性的抑制提示词(例如:输入“person, young”)。然后按“训练”按钮。使用默认设置,训练一个滑块大约需要25分钟;然后您可以在上面的“测试”选项卡中尝试推理或下载权重。为了更快的训练,请复制此存储库并使用A100或更大的GPU进行训练。代码和详细信息在[github链接](https://github.com/rohitgandikota/sliders)。')
171
+
172
+ with gr.Row():
173
+
174
+ with gr.Column(scale=3):
175
+
176
+ self.target_concept = gr.Text(
177
+ placeholder="输入要进行编辑的目标概念...",
178
+ label="编辑概念的提示词",
179
+ info="对应于要编辑的概念的提示词(例如:“person”)",
180
+ value = ''
181
+ )
182
+
183
+ self.positive_prompt = gr.Text(
184
+ placeholder="输入编辑的增强提示词...",
185
+ label="增强提示词",
186
+ info="对应于要增强的概念的提示词(例如:“person, old”)",
187
+ value = ''
188
+ )
189
+
190
+ self.negative_prompt = gr.Text(
191
+ placeholder="输入编辑的抑制提示词...",
192
+ label="抑制提示词",
193
+ info="对应于要抑制的概念的提示词(例如:“person, young”)",
194
+ value = ''
195
+ )
196
+
197
+ self.attributes_input = gr.Text(
198
+ placeholder="输入要保留的概念(用逗号分隔)。如果不需要,请留空...",
199
+ label="要保留的概念",
200
+ info="要保留/解缠的概念(例如:“male, female”)",
201
+ value = ''
202
+ )
203
+ self.is_person = gr.Checkbox(
204
+ label="人",
205
+ info="您是否在为人训练滑块?")
206
+
207
+ self.rank = gr.Number(
208
+ value=4,
209
+ label="滑块等级",
210
+ info='要训练的滑块等级'
211
+ )
212
+ choices = ['xattn', 'noxattn']
213
+ self.train_method_input = gr.Dropdown(
214
+ choices=choices,
215
+ value='xattn',
216
+ label='训练方法',
217
+ info='训练方法。如果[* xattn *] - loras将仅在交叉注意层上。如果[* noxattn *](官方实现) - 除交叉注意层外的所有层',
218
+ interactive=True
219
+ )
220
+ self.iterations_input = gr.Number(
221
+ value=500,
222
+ precision=0,
223
+ label="迭代次数",
224
+ info='用于训练的迭代次数 - 最大为1000'
225
+ )
226
+
227
+ self.lr_input = gr.Number(
228
+ value=2e-4,
229
+ label="学习率",
230
+ info='用于训练的学习率'
231
+ )
232
+
233
+ with gr.Column(scale=1):
234
+
235
+ self.train_status = gr.Button(value='', variant='primary', interactive=False)
236
+
237
+ self.train_button = gr.Button(
238
+ value="训练",
239
+ )
240
+
241
+ self.download = gr.Files()
242
+
243
+ self.infr_button.click(self.inference, inputs = [
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  self.prompt_input_infr,
245
+ self.seed_infr,
246
  self.start_noise_infr,
247
+ self.slider_scale_infr,
248
+ self.model_dropdown,
249
+ self.model_type
250
  ],
251
  outputs=[
252
  self.image_new,
 
267
  outputs=[self.train_button, self.train_status, self.download, self.model_dropdown]
268
  )
269
 
 
 
 
 
 
 
270
  def train(self, target_concept,positive_prompt, negative_prompt, rank, iterations_input, lr_input, attributes_input, is_person, train_method_input, pbar = gr.Progress(track_tqdm=True)):
271
  iterations_input = min(int(iterations_input),1000)
272
  if attributes_input == '':
 
297
 
298
  return [gr.update(interactive=True, value='Train'), gr.update(value='Done Training! \n Try your custom slider in the "Test" tab'), f'models/{save_name}', gr.update(choices=list(model_map.keys()), value=save_name.replace('.pt',''))]
299
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
300
 
301
+ def inference(self, prompt, seed, start_noise, scale, model_names, model, pbar = gr.Progress(track_tqdm=True)):
302
+
303
+ seed = seed or 42753
 
 
 
 
304
  if self.current_model != model:
305
  if model=='SDXL Turbo':
306
  model_id = "stabilityai/sdxl-turbo"
307
  euler_anc = EulerAncestralDiscreteScheduler.from_pretrained(model_id, subfolder="scheduler")
308
  self.pipe = StableDiffusionXLPipeline.from_pretrained(model_id, scheduler=euler_anc, torch_dtype=self.weight_dtype).to(self.device)
309
+ self.pipe.enable_xformers_memory_efficient_attention()
 
310
  self.guidance_scale = 1
311
  self.num_inference_steps = 3
312
  self.current_model = 'SDXL Turbo'
313
  else:
314
  model_id = 'stabilityai/stable-diffusion-xl-base-1.0'
315
  self.pipe = StableDiffusionXLPipeline.from_pretrained(model_id, torch_dtype=self.weight_dtype).to(self.device)
316
+ self.pipe.enable_xformers_memory_efficient_attention()
 
317
  self.guidance_scale = 7.5
318
  self.num_inference_steps = 20
319
  self.current_model = 'SDXL'
320
+ generator = torch.manual_seed(seed)
321
+
322
  networks = []
323
  for model_name in model_names:
324
  model_path = model_map[model_name]
 
346
  if 'alpha1' in model_path:
347
  alpha = 1.0
348
  network = LoRANetwork(
349
+ unet,
350
+ rank=rank,
351
+ multiplier=1.0,
352
+ alpha=alpha,
353
+ train_method=train_method,
354
+ ).to(self.device, dtype=self.weight_dtype)
355
+ network.load_state_dict(torch.load(model_path))
356
  networks.append(network)
357
 
358
+ generator = torch.manual_seed(seed)
359
+ edited_image = self.pipe(prompt, num_images_per_prompt=1, num_inference_steps=self.num_inference_steps, generator=generator, networks=networks, start_noise=int(start_noise), scale=float(scale), unet=unet, guidance_scale=self.guidance_scale).images[0]
360
+
361
+ generator = torch.manual_seed(seed)
362
+ original_image = self.pipe(prompt, num_images_per_prompt=1, num_inference_steps=self.num_inference_steps, generator=generator, networks=networks, start_noise=start_noise, scale=0, unet=unet, guidance_scale=self.guidance_scale).images[0]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
363
 
364
  del unet, networks
365
  unet = None