Spaces:
Running
Running
fix: 交互逻辑重构
Browse files- app.py +124 -182
- clean_deps.bat +5 -0
- install_deps.bat +4 -1
- requirements-win.txt +23 -0
app.py
CHANGED
@@ -70,7 +70,6 @@ class Demo:
|
|
70 |
self.generating = False
|
71 |
self.weight_dtype = torch.bfloat16
|
72 |
self.model_sections = []
|
73 |
-
self.model_sections_count = gr.State(0)
|
74 |
|
75 |
model_id = 'stabilityai/stable-diffusion-xl-base-1.0'
|
76 |
if torch.cuda.is_available():
|
@@ -94,185 +93,152 @@ class Demo:
|
|
94 |
self.num_inference_steps = 3
|
95 |
|
96 |
with gr.Blocks() as demo:
|
97 |
-
@gr.render(inputs=self.model_sections_count)
|
98 |
-
def render_model_sections(count):
|
99 |
-
print("Adding model section")
|
100 |
-
for i in range(count):
|
101 |
-
# 创建新的模块布局
|
102 |
-
with gr.Row(visible=True) as new_section:
|
103 |
-
with gr.Column():
|
104 |
-
gr.Markdown(f"### 模块 {i + 1}")
|
105 |
-
model_dropdown = gr.Dropdown(
|
106 |
-
label="预训练模型选择",
|
107 |
-
choices=list(model_map.keys()),
|
108 |
-
value="年龄调整",
|
109 |
-
interactive=True,
|
110 |
-
)
|
111 |
-
seed_infr = gr.Number(
|
112 |
-
label="种子值",
|
113 |
-
value=42753,
|
114 |
-
)
|
115 |
-
slider_scale_infr = gr.Slider(
|
116 |
-
minimum=-4,
|
117 |
-
maximum=4,
|
118 |
-
label="编辑强度",
|
119 |
-
value=3,
|
120 |
-
info="较大的值会导致更强的编辑效果",
|
121 |
-
)
|
122 |
-
# del_btn = gr.Button(value="删除", elem_classes="del-btn")
|
123 |
-
|
124 |
-
# # 删除按钮的逻辑
|
125 |
-
# def delete_section():
|
126 |
-
# if new_section in self.model_sections:
|
127 |
-
# self.model_sections.remove(new_section)
|
128 |
-
# return gr.update(visible=False)
|
129 |
-
|
130 |
-
# del_btn.click(delete_section, outputs=new_section)
|
131 |
-
# 添加新模块到 sections 列表
|
132 |
-
self.model_sections.append(new_section)
|
133 |
-
|
134 |
self.layout()
|
135 |
demo.queue(max_size=5).launch(share=True, max_threads=2)
|
136 |
|
137 |
|
138 |
def layout(self):
|
139 |
-
with gr.Row():
|
140 |
|
141 |
-
|
142 |
|
143 |
-
|
144 |
|
145 |
-
with gr.Row():
|
146 |
|
147 |
-
|
148 |
|
149 |
-
|
150 |
|
151 |
-
|
152 |
|
153 |
-
|
154 |
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
161 |
|
162 |
-
self.
|
|
|
|
|
|
|
|
|
163 |
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
170 |
)
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
|
|
176 |
)
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
181 |
interactive=True
|
182 |
)
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
label="
|
187 |
-
|
188 |
-
type='pil',
|
189 |
)
|
190 |
-
|
191 |
-
self.
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
)
|
196 |
|
197 |
-
|
198 |
|
199 |
-
|
200 |
|
201 |
-
self.
|
|
|
|
|
202 |
|
203 |
-
|
|
|
204 |
|
205 |
-
with gr.Column(scale=3):
|
206 |
-
|
207 |
-
self.target_concept = gr.Text(
|
208 |
-
placeholder="输入要进行编辑的目标概念...",
|
209 |
-
label="编辑概念的提示词",
|
210 |
-
info="对应于要编辑的概念的提示词(例如:“person”)",
|
211 |
-
value = ''
|
212 |
-
)
|
213 |
-
|
214 |
-
self.positive_prompt = gr.Text(
|
215 |
-
placeholder="输入编辑的增强提示词...",
|
216 |
-
label="增强提示词",
|
217 |
-
info="对应于要增强的概念的提示词(例如:“person, old”)",
|
218 |
-
value = ''
|
219 |
-
)
|
220 |
-
|
221 |
-
self.negative_prompt = gr.Text(
|
222 |
-
placeholder="输入编辑的抑制提示词...",
|
223 |
-
label="抑制提示词",
|
224 |
-
info="对应于要抑制的概念的提示词(例如:“person, young”)",
|
225 |
-
value = ''
|
226 |
-
)
|
227 |
-
|
228 |
-
self.attributes_input = gr.Text(
|
229 |
-
placeholder="输入要保留的概念(用逗号分隔)。如果不需要,请留空...",
|
230 |
-
label="要保留的概念",
|
231 |
-
info="要保留/解缠的概念(例如:“male, female”)",
|
232 |
-
value = ''
|
233 |
-
)
|
234 |
-
self.is_person = gr.Checkbox(
|
235 |
-
label="人",
|
236 |
-
info="您是否在为人训练滑块?")
|
237 |
-
|
238 |
-
self.rank = gr.Number(
|
239 |
-
value=4,
|
240 |
-
label="滑块等级",
|
241 |
-
info='要训练的滑块等级'
|
242 |
-
)
|
243 |
-
choices = ['xattn', 'noxattn']
|
244 |
-
self.train_method_input = gr.Dropdown(
|
245 |
-
choices=choices,
|
246 |
-
value='xattn',
|
247 |
-
label='训练方法',
|
248 |
-
info='训练方法。如果[* xattn *] - loras将仅在交叉注意层上。如果[* noxattn *](官方实现) - 除交叉注意层外的所有层',
|
249 |
-
interactive=True
|
250 |
-
)
|
251 |
-
self.iterations_input = gr.Number(
|
252 |
-
value=500,
|
253 |
-
precision=0,
|
254 |
-
label="迭代次数",
|
255 |
-
info='用于训练的迭代次数 - 最大为1000'
|
256 |
-
)
|
257 |
-
|
258 |
-
self.lr_input = gr.Number(
|
259 |
-
value=2e-4,
|
260 |
-
label="学习率",
|
261 |
-
info='用于训练的学习率'
|
262 |
-
)
|
263 |
-
|
264 |
-
with gr.Column(scale=1):
|
265 |
-
|
266 |
-
self.train_status = gr.Button(value='', variant='primary', interactive=False)
|
267 |
-
|
268 |
-
self.train_button = gr.Button(
|
269 |
-
value="训练",
|
270 |
-
)
|
271 |
-
|
272 |
-
self.download = gr.Files()
|
273 |
-
self.model_dropdown = gr.Dropdown(choices=list(model_map.keys()))
|
274 |
-
|
275 |
-
self.add_model_button.click(lambda x: x + 1, self.model_sections_count, self.model_sections_count)
|
276 |
self.infr_button.click(self.inference, inputs=[
|
277 |
self.prompt_input_infr,
|
278 |
self.start_noise_infr,
|
@@ -296,30 +262,6 @@ class Demo:
|
|
296 |
],
|
297 |
outputs=[self.train_button, self.train_status, self.download, self.model_dropdown]
|
298 |
)
|
299 |
-
|
300 |
-
# def add_model_section(self):
|
301 |
-
# with self.model_sections:
|
302 |
-
# model_dropdown = gr.Dropdown(
|
303 |
-
# label="预训练滑块",
|
304 |
-
# choices=list(model_map.keys()),
|
305 |
-
# value='年龄调整',
|
306 |
-
# interactive=True
|
307 |
-
# )
|
308 |
-
# seed_infr = gr.Number(
|
309 |
-
# label="种子值",
|
310 |
-
# value=42753
|
311 |
-
# )
|
312 |
-
# slider_scale_infr = gr.Slider(
|
313 |
-
# -4,
|
314 |
-
# 4,
|
315 |
-
# label="滑块刻度",
|
316 |
-
# value=3,
|
317 |
-
# info="较大的滑块刻度会导致更强的编辑效果"
|
318 |
-
# )
|
319 |
-
# self.model_sections.add_child(model_dropdown)
|
320 |
-
# self.model_sections.add_child(seed_infr)
|
321 |
-
# self.model_sections.add_child(slider_scale_infr)
|
322 |
-
# return gr.update(visible=True, children=self.model_sections.children)
|
323 |
|
324 |
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)):
|
325 |
iterations_input = min(int(iterations_input),1000)
|
@@ -353,10 +295,10 @@ class Demo:
|
|
353 |
|
354 |
|
355 |
def inference(self, prompt, start_noise, model, pbar=gr.Progress(track_tqdm=True)):
|
356 |
-
model_sections = self.model_sections
|
357 |
-
model_names = [section[0].value for section in model_sections]
|
358 |
-
seed_list = [section[1].value for section in model_sections]
|
359 |
-
scale_list = [section[2].value for section in model_sections]
|
360 |
|
361 |
if self.current_model != model:
|
362 |
if model=='SDXL Turbo':
|
|
|
70 |
self.generating = False
|
71 |
self.weight_dtype = torch.bfloat16
|
72 |
self.model_sections = []
|
|
|
73 |
|
74 |
model_id = 'stabilityai/stable-diffusion-xl-base-1.0'
|
75 |
if torch.cuda.is_available():
|
|
|
93 |
self.num_inference_steps = 3
|
94 |
|
95 |
with gr.Blocks() as demo:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
self.layout()
|
97 |
demo.queue(max_size=5).launch(share=True, max_threads=2)
|
98 |
|
99 |
|
100 |
def layout(self):
|
101 |
+
# with gr.Row():
|
102 |
|
103 |
+
# if SPACE_ID == ORIGINAL_SPACE_ID:
|
104 |
|
105 |
+
# self.warning = gr.Markdown(SHARED_UI_WARNING)
|
106 |
|
107 |
+
# with gr.Row():
|
108 |
|
109 |
+
with gr.Tab("测试") as inference_column:
|
110 |
|
111 |
+
with gr.Row():
|
112 |
|
113 |
+
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>')
|
114 |
|
115 |
+
with gr.Row():
|
116 |
|
117 |
+
self.prompt_input_infr = gr.Text(
|
118 |
+
placeholder="photo of a person, with bokeh street background, realistic, 8k",
|
119 |
+
label="提示词",
|
120 |
+
info="生成图像的提示词",
|
121 |
+
value="photo of a person, with bokeh street background, realistic, 8k"
|
122 |
+
)
|
123 |
+
|
124 |
+
for model_name in model_map.keys():
|
125 |
+
with gr.Row():
|
126 |
+
model_checkbox = gr.Checkbox(label=model_name, value=False)
|
127 |
+
seed_infr = gr.Number(label="种子值", value=42753)
|
128 |
+
slider_scale_infr = gr.Slider(-4, 4, label="滑块刻度", value=3, info="较大的滑块刻度会导致更强的编辑效果")
|
129 |
+
self.model_sections.append((model_checkbox, seed_infr, slider_scale_infr))
|
130 |
+
|
131 |
+
with gr.Row():
|
132 |
+
self.start_noise_infr = gr.Slider(
|
133 |
+
600, 900,
|
134 |
+
value=750,
|
135 |
+
label="SDEdit时间步",
|
136 |
+
info="选择较小的值以保持更多结构"
|
137 |
+
)
|
138 |
+
self.model_type = gr.Dropdown(
|
139 |
+
label="模型",
|
140 |
+
choices=['SDXL Turbo', 'SDXL'],
|
141 |
+
value='SDXL Turbo',
|
142 |
+
interactive=True
|
143 |
+
)
|
144 |
+
|
145 |
+
with gr.Row():
|
146 |
+
self.infr_button = gr.Button(
|
147 |
+
value="生成",
|
148 |
+
interactive=True
|
149 |
+
)
|
150 |
+
|
151 |
+
with gr.Row():
|
152 |
+
self.image_orig = gr.Image(
|
153 |
+
label="原始SD",
|
154 |
+
interactive=False,
|
155 |
+
type='pil',
|
156 |
+
)
|
157 |
|
158 |
+
self.image_new = gr.Image(
|
159 |
+
label=f"概念滑块",
|
160 |
+
interactive=False,
|
161 |
+
type='pil',
|
162 |
+
)
|
163 |
|
164 |
+
with gr.Tab("训练") as training_column:
|
165 |
+
|
166 |
+
with gr.Row():
|
167 |
+
|
168 |
+
self.explain_train= gr.Markdown(value='在这一部分,您可以为Stable Diffusion XL训练文本概念滑块。输入您希望进行编辑的目标概念(例如:人)。接下来,输入您希望编辑的属性的增强提示词(例如:控制人的年龄,输入“person, old”)。然后,输入属性的抑制提示词(例如:输入“person, young”)。然后按“训练”按钮。使用默认设置,训练一个滑块大约需要25分钟;然后您可以在上面的“测试”选项卡中尝试推理或下载权重。为了更快的训练,请复制此存储库并使用A100或更大的GPU进行训练。代码和详细信息在[github链接](https://github.com/rohitgandikota/sliders)。')
|
169 |
+
|
170 |
+
with gr.Row():
|
171 |
+
|
172 |
+
with gr.Column(scale=3):
|
173 |
+
|
174 |
+
self.target_concept = gr.Text(
|
175 |
+
placeholder="输入要进行编辑的目标概念...",
|
176 |
+
label="编辑概念的提示词",
|
177 |
+
info="对应于要编辑的概念的提示词(例如:“person”)",
|
178 |
+
value = ''
|
179 |
)
|
180 |
+
|
181 |
+
self.positive_prompt = gr.Text(
|
182 |
+
placeholder="输入编辑的增强提示词...",
|
183 |
+
label="增强提示词",
|
184 |
+
info="对应于要增强的概念的提示词(例如:“person, old”)",
|
185 |
+
value = ''
|
186 |
)
|
187 |
+
|
188 |
+
self.negative_prompt = gr.Text(
|
189 |
+
placeholder="输入编辑的抑制提示词...",
|
190 |
+
label="抑制提示词",
|
191 |
+
info="对应于要抑制的概念的提示词(例如:“person, young”)",
|
192 |
+
value = ''
|
193 |
+
)
|
194 |
+
|
195 |
+
self.attributes_input = gr.Text(
|
196 |
+
placeholder="输入要保留的概念(用逗号分隔)。如果不需要,请留空...",
|
197 |
+
label="要保留的概念",
|
198 |
+
info="要保留/解缠的概念(例如:“male, female”)",
|
199 |
+
value = ''
|
200 |
+
)
|
201 |
+
self.is_person = gr.Checkbox(
|
202 |
+
label="人",
|
203 |
+
info="您是否在为人训练滑块?")
|
204 |
+
|
205 |
+
self.rank = gr.Number(
|
206 |
+
value=4,
|
207 |
+
label="滑块等级",
|
208 |
+
info='要训练的滑块等级'
|
209 |
+
)
|
210 |
+
choices = ['xattn', 'noxattn']
|
211 |
+
self.train_method_input = gr.Dropdown(
|
212 |
+
choices=choices,
|
213 |
+
value='xattn',
|
214 |
+
label='训练方法',
|
215 |
+
info='训练方法。如果[* xattn *] - loras将仅在交叉注意层上。如果[* noxattn *](官方实现) - 除交叉注意层外的所有层',
|
216 |
interactive=True
|
217 |
)
|
218 |
+
self.iterations_input = gr.Number(
|
219 |
+
value=500,
|
220 |
+
precision=0,
|
221 |
+
label="迭代次数",
|
222 |
+
info='用于训练的迭代次数 - 最大为1000'
|
|
|
223 |
)
|
224 |
+
|
225 |
+
self.lr_input = gr.Number(
|
226 |
+
value=2e-4,
|
227 |
+
label="学习率",
|
228 |
+
info='用于训练的学习率'
|
229 |
)
|
230 |
|
231 |
+
with gr.Column(scale=1):
|
232 |
|
233 |
+
self.train_status = gr.Button(value='', variant='primary', interactive=False)
|
234 |
|
235 |
+
self.train_button = gr.Button(
|
236 |
+
value="训练",
|
237 |
+
)
|
238 |
|
239 |
+
self.download = gr.Files()
|
240 |
+
self.model_dropdown = gr.Dropdown(choices=list(model_map.keys()))
|
241 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
242 |
self.infr_button.click(self.inference, inputs=[
|
243 |
self.prompt_input_infr,
|
244 |
self.start_noise_infr,
|
|
|
262 |
],
|
263 |
outputs=[self.train_button, self.train_status, self.download, self.model_dropdown]
|
264 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
265 |
|
266 |
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)):
|
267 |
iterations_input = min(int(iterations_input),1000)
|
|
|
295 |
|
296 |
|
297 |
def inference(self, prompt, start_noise, model, pbar=gr.Progress(track_tqdm=True)):
|
298 |
+
model_sections = self.model_sections
|
299 |
+
model_names = [section[0].value for section in model_sections if section[0].value]
|
300 |
+
seed_list = [section[1].value for section in model_sections if section[0].value]
|
301 |
+
scale_list = [section[2].value for section in model_sections if section[0].value]
|
302 |
|
303 |
if self.current_model != model:
|
304 |
if model=='SDXL Turbo':
|
clean_deps.bat
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
pip freeze > clean_requirements.txt
|
2 |
+
|
3 |
+
pip uninstall -r clean_requirements.txt -y
|
4 |
+
|
5 |
+
del clean_requirements.txt
|
install_deps.bat
CHANGED
@@ -1,4 +1,7 @@
|
|
1 |
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124
|
2 |
pip install -U xformers --index-url https://download.pytorch.org/whl/cu124
|
3 |
-
pip install -
|
|
|
|
|
|
|
4 |
pip install --upgrade gradio
|
|
|
1 |
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124
|
2 |
pip install -U xformers --index-url https://download.pytorch.org/whl/cu124
|
3 |
+
pip install 'https://github.com/bitsandbytes-foundation/bitsandbytes/releases/download/continuous-release_multi-backend-refactor/bitsandbytes-0.44.1.dev0-py3-none-win_amd64.whl'
|
4 |
+
|
5 |
+
pip install -r requirements-win.txt
|
6 |
+
|
7 |
pip install --upgrade gradio
|
requirements-win.txt
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
dadaptation==3.1
|
2 |
+
diffusers==0.32.2
|
3 |
+
ipython==8.7.0
|
4 |
+
lion_pytorch==0.1.2
|
5 |
+
lpips==0.1.4
|
6 |
+
matplotlib==3.6.2
|
7 |
+
numpy==1.23.5
|
8 |
+
opencv_python==4.5.5.64
|
9 |
+
opencv_python_headless==4.7.0.68
|
10 |
+
pandas==1.5.2
|
11 |
+
Pillow==10.1.0
|
12 |
+
prodigyopt==1.0
|
13 |
+
pydantic==2.10.5
|
14 |
+
PyYAML==6.0.1
|
15 |
+
Requests==2.31.0
|
16 |
+
safetensors==0.5.2
|
17 |
+
tqdm==4.64.1
|
18 |
+
transformers==4.48.1
|
19 |
+
wandb==0.12.21
|
20 |
+
accelerate==1.3.0
|
21 |
+
gradio==5.12.0
|
22 |
+
gradio_client==1.5.4
|
23 |
+
huggingface-hub==0.27.1
|