developerskyebrowse commited on
Commit
ce22ab0
·
1 Parent(s): 105ac9e
Files changed (4) hide show
  1. .gitignore +2 -1
  2. Dockerfile +2 -2
  3. anime_app.py +14 -9
  4. profiler.py +0 -381
.gitignore CHANGED
@@ -5,4 +5,5 @@ anime_app_local.py
5
  *.jpg
6
  *.png
7
  *.pyc
8
- client.py
 
 
5
  *.jpg
6
  *.png
7
  *.pyc
8
+ client.py
9
+ outputs/*
Dockerfile CHANGED
@@ -33,8 +33,8 @@ ENV HOME=/home/user \
33
 
34
  RUN pip3 install --no-cache-dir --upgrade -r /code/requirements.txt
35
 
36
- RUN apt-get install -y nvidia-340
37
- RUN nvidia-smi
38
 
39
  # Set the working directory to the user's home directory
40
  WORKDIR $HOME/app
 
33
 
34
  RUN pip3 install --no-cache-dir --upgrade -r /code/requirements.txt
35
 
36
+ #RUN apt-get install -y nvidia-340
37
+ #RUN nvidia-smi
38
 
39
  # Set the working directory to the user's home directory
40
  WORKDIR $HOME/app
anime_app.py CHANGED
@@ -1,6 +1,8 @@
1
  prod = True
 
2
  show_options = True
3
  if prod:
 
4
  show_options = False
5
  import os
6
  import gc
@@ -8,6 +10,7 @@ import random
8
  import time
9
  import gradio as gr
10
  import spaces
 
11
  import imageio
12
  from huggingface_hub import HfApi
13
  import torch
@@ -18,8 +21,7 @@ from diffusers import (
18
  StableDiffusionControlNetPipeline,
19
  )
20
  from preprocess_anime import Preprocessor
21
- # MAX_SEED = np.iinfo(np.int32).max
22
- MAX_SEED = 2147483647
23
  API_KEY = os.environ.get("API_KEY", None)
24
 
25
  print("CUDA version:", torch.version.cuda)
@@ -98,6 +100,7 @@ def get_additional_prompt():
98
 
99
  def get_prompt(prompt, additional_prompt):
100
  default = "hyperrealistic photography,extremely detailed,(intricate details),unity 8k wallpaper,ultra detailed"
 
101
  randomize = get_additional_prompt()
102
  # nude = "NSFW,((nude)),medium bare breasts,hyperrealistic photography,extremely detailed,(intricate details),unity 8k wallpaper,ultra detailed"
103
  # bodypaint = "((fully naked with no clothes)),nude naked seethroughxray,invisiblebodypaint,rating_newd,NSFW"
@@ -113,17 +116,18 @@ def get_prompt(prompt, additional_prompt):
113
  naked_hoodie = "hyperrealistic photography, extremely detailed, medium hair, cityscape, (neon lights), score_9, HDA_NakedHoodie"
114
  abg = "(1girl, asian body covered in words, words on body, tattoos of (words) on body),(masterpiece, best quality),medium breasts,(intricate details),unity 8k wallpaper,ultra detailed,(pastel colors),beautiful and aesthetic,see-through (clothes),detailed,solo"
115
  # shibari = "extremely detailed, hyperrealistic photography, earrings, blushing, lace choker, tattoo, medium hair, score_9, HDA_Shibari"
116
- shibari2 = "extremely detailed, hyperrealistic photography,earrings,tattoo,score_9, HDA_Shibari"
117
 
118
  if prompt == "":
119
- prompts = [randomize, pet_play, bondage, lab_girl, athleisure, atompunk, maid, nundress, naked_hoodie, abg, shibari2, ahegao2]
120
  prompts_nsfw = [abg, shibari2, ahegao2]
121
  preset = random.choice(prompts)
122
  prompt = f"{preset}"
123
  # print(f"-------------{preset}-------------")
124
  else:
125
  # prompt = f"{prompt}, {randomize}"
126
- prompt = f"{default},{prompt}"
 
127
  print(f"{prompt}")
128
  return prompt
129
 
@@ -237,7 +241,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
237
  step=1,
238
  )
239
  num_steps = gr.Slider(
240
- label="Number of steps", minimum=1, maximum=100, value=12, step=1
241
  ) # 20/4.5 or 12 without lora, 4 with lora
242
  guidance_scale = gr.Slider(
243
  label="Guidance scale", minimum=0.1, maximum=30.0, value=5.5, step=0.1
@@ -267,7 +271,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
267
  sources=["upload"],
268
  show_label=True,
269
  mirror_webcam=True,
270
- format="jpg",
271
  )
272
  # run button
273
  with gr.Column():
@@ -277,7 +281,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
277
  result = gr.Image(
278
  label="Anime AI",
279
  interactive=False,
280
- format="jpg",
281
  show_share_button= False,
282
  )
283
  # Use this image button
@@ -330,4 +334,5 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
330
  def turn_buttons_on():
331
  return gr.update(visible=True), gr.update(visible=True)
332
 
333
- demo.queue(api_open=False).launch(show_api=False)
 
 
1
  prod = True
2
+ port = 8080
3
  show_options = True
4
  if prod:
5
+ port = 8081
6
  show_options = False
7
  import os
8
  import gc
 
10
  import time
11
  import gradio as gr
12
  import spaces
13
+ import numpy as np
14
  import imageio
15
  from huggingface_hub import HfApi
16
  import torch
 
21
  StableDiffusionControlNetPipeline,
22
  )
23
  from preprocess_anime import Preprocessor
24
+ MAX_SEED = np.iinfo(np.int32).max
 
25
  API_KEY = os.environ.get("API_KEY", None)
26
 
27
  print("CUDA version:", torch.version.cuda)
 
100
 
101
  def get_prompt(prompt, additional_prompt):
102
  default = "hyperrealistic photography,extremely detailed,(intricate details),unity 8k wallpaper,ultra detailed"
103
+ default2 = f"professional 3d model {prompt},octane render,highly detailed,volumetric,dramatic lighting,hyperrealistic photography,extremely detailed,(intricate details),unity 8k wallpaper,ultra detailed"
104
  randomize = get_additional_prompt()
105
  # nude = "NSFW,((nude)),medium bare breasts,hyperrealistic photography,extremely detailed,(intricate details),unity 8k wallpaper,ultra detailed"
106
  # bodypaint = "((fully naked with no clothes)),nude naked seethroughxray,invisiblebodypaint,rating_newd,NSFW"
 
116
  naked_hoodie = "hyperrealistic photography, extremely detailed, medium hair, cityscape, (neon lights), score_9, HDA_NakedHoodie"
117
  abg = "(1girl, asian body covered in words, words on body, tattoos of (words) on body),(masterpiece, best quality),medium breasts,(intricate details),unity 8k wallpaper,ultra detailed,(pastel colors),beautiful and aesthetic,see-through (clothes),detailed,solo"
118
  # shibari = "extremely detailed, hyperrealistic photography, earrings, blushing, lace choker, tattoo, medium hair, score_9, HDA_Shibari"
119
+ shibari2 = "octane render, highly detailed, volumetric, HDA_Shibari"
120
 
121
  if prompt == "":
122
+ prompts = [randomize, pet_play, bondage, lab_girl, athleisure, atompunk, maid, nundress, naked_hoodie, abg, shibari2]
123
  prompts_nsfw = [abg, shibari2, ahegao2]
124
  preset = random.choice(prompts)
125
  prompt = f"{preset}"
126
  # print(f"-------------{preset}-------------")
127
  else:
128
  # prompt = f"{prompt}, {randomize}"
129
+ # prompt = f"{default},{prompt}"
130
+ prompt = default2
131
  print(f"{prompt}")
132
  return prompt
133
 
 
241
  step=1,
242
  )
243
  num_steps = gr.Slider(
244
+ label="Number of steps", minimum=1, maximum=100, value=15, step=1
245
  ) # 20/4.5 or 12 without lora, 4 with lora
246
  guidance_scale = gr.Slider(
247
  label="Guidance scale", minimum=0.1, maximum=30.0, value=5.5, step=0.1
 
271
  sources=["upload"],
272
  show_label=True,
273
  mirror_webcam=True,
274
+ format="webp",
275
  )
276
  # run button
277
  with gr.Column():
 
281
  result = gr.Image(
282
  label="Anime AI",
283
  interactive=False,
284
+ format="webp",
285
  show_share_button= False,
286
  )
287
  # Use this image button
 
334
  def turn_buttons_on():
335
  return gr.update(visible=True), gr.update(visible=True)
336
 
337
+ # demo.queue(api_open=False).launch(show_api=False)
338
+ demo.queue(max_size=20).launch(server_name="localhost", server_port=port)
profiler.py DELETED
@@ -1,381 +0,0 @@
1
- import cProfile
2
- import pstats
3
- import io
4
- import gc
5
- import random
6
- import time
7
- import gradio as gr
8
- import spaces
9
- import imageio
10
- from huggingface_hub import HfApi
11
- import torch
12
- from PIL import Image
13
- from diffusers import (
14
- ControlNetModel,
15
- DPMSolverMultistepScheduler,
16
- StableDiffusionControlNetPipeline,
17
- )
18
- from preprocess_anime import Preprocessor, conditionally_manage_memory
19
- from settings import API_KEY, MAX_NUM_IMAGES, MAX_SEED
20
-
21
- preprocessor = None
22
- controlnet = None
23
- scheduler = None
24
- pipe = None
25
- compiled = False
26
- api = HfApi()
27
-
28
- def randomize_seed_fn(seed: int, randomize_seed: bool) -> int:
29
- if randomize_seed:
30
- seed = random.randint(0, MAX_SEED)
31
- return seed
32
-
33
- def get_additional_prompt():
34
- prompt = "hyperrealistic photography,extremely detailed,(intricate details),unity 8k wallpaper,ultra detailed"
35
- top = ["tank top", "blouse", "button up shirt", "sweater", "corset top"]
36
- bottom = ["short skirt", "athletic shorts", "jean shorts", "pleated skirt", "short skirt", "leggings", "high-waisted shorts"]
37
- accessory = ["knee-high boots", "gloves", "Thigh-high stockings", "Garter belt", "choker", "necklace", "headband", "headphones"]
38
- return f"{prompt}, {random.choice(top)}, {random.choice(bottom)}, {random.choice(accessory)}, score_9"
39
- # outfit = ["schoolgirl outfit", "playboy outfit", "red dress", "gala dress", "cheerleader outfit", "nurse outfit", "Kimono"]
40
-
41
- def get_prompt(prompt, additional_prompt):
42
- default = "hyperrealistic photography,extremely detailed,(intricate details),unity 8k wallpaper,ultra detailed"
43
- randomize = get_additional_prompt()
44
- nude = "NSFW,((nude)),medium bare breasts,hyperrealistic photography,extremely detailed,(intricate details),unity 8k wallpaper,ultra detailed"
45
- bodypaint = "((fully naked with no clothes)),nude naked seethroughxray,invisiblebodypaint,rating_newd,NSFW"
46
- lab_girl = "hyperrealistic photography, extremely detailed, shy assistant wearing minidress boots and gloves, laboratory background, score_9, 1girl"
47
- pet_play = "hyperrealistic photography, extremely detailed, playful, blush, glasses, collar, score_9, HDA_pet_play"
48
- bondage = "hyperrealistic photography, extremely detailed, submissive, glasses, score_9, HDA_Bondage"
49
- ahegao = "((invisible clothing)), hyperrealistic photography,exposed vagina,sexy,nsfw,HDA_Ahegao"
50
- ahegao2 = "(invisiblebodypaint),rating_newd,HDA_Ahegao"
51
- athleisure = "hyperrealistic photography, extremely detailed, 1girl athlete, exhausted embarrassed sweaty,outdoors, ((athleisure clothing)), score_9"
52
- atompunk = "((atompunk world)), hyperrealistic photography, extremely detailed, short hair, bodysuit, glasses, neon cyberpunk background, score_9"
53
- maid = "hyperrealistic photography, extremely detailed, shy, blushing, score_9, pastel background, HDA_unconventional_maid"
54
- nundress = "hyperrealistic photography, extremely detailed, shy, blushing, fantasy background, score_9, HDA_NunDress"
55
- naked_hoodie = "hyperrealistic photography, extremely detailed, medium hair, cityscape, (neon lights), score_9, HDA_NakedHoodie"
56
- abg = "(1girl, asian body covered in words, words on body, tattoos of (words) on body),(masterpiece, best quality),medium breasts,(intricate details),unity 8k wallpaper,ultra detailed,(pastel colors),beautiful and aesthetic,see-through (clothes),detailed,solo"
57
- shibari = "extremely detailed, hyperrealistic photography, earrings, blushing, lace choker, tattoo, medium hair, score_9, HDA_Shibari"
58
-
59
- if prompt == "":
60
- prompts = [randomize, nude, bodypaint, pet_play, bondage, ahegao2, lab_girl, athleisure, atompunk, maid, nundress, naked_hoodie, abg, shibari]
61
- prompts_nsfw = [nude, bodypaint, abg, ahegao2, shibari]
62
- preset = random.choice(prompts)
63
- prompt = f"{preset}"
64
- # print(f"-------------{preset}-------------")
65
- else:
66
- # prompt = f"{prompt}, {randomize}"
67
- prompt = f"{default},{prompt}"
68
- print(f"{prompt}")
69
- return prompt
70
-
71
- def initialize_models():
72
- global preprocessor, controlnet, scheduler, pipe
73
- if preprocessor is None:
74
- preprocessor = Preprocessor()
75
-
76
- if controlnet is None:
77
- model_id = "lllyasviel/control_v11p_sd15_normalbae"
78
- print("initializing controlnet")
79
- controlnet = ControlNetModel.from_pretrained(
80
- model_id,
81
- torch_dtype=torch.float16,
82
- attn_implementation="flash_attention_2",
83
- ).to("cuda")
84
-
85
- if scheduler is None:
86
- scheduler = DPMSolverMultistepScheduler.from_pretrained(
87
- "runwayml/stable-diffusion-v1-5",
88
- solver_order=2,
89
- subfolder="scheduler",
90
- use_karras_sigmas=True,
91
- final_sigmas_type="sigma_min",
92
- algorithm_type="sde-dpmsolver++",
93
- prediction_type="epsilon",
94
- thresholding=False,
95
- denoise_final=True,
96
- device_map="cuda",
97
- )
98
-
99
- if pipe is None:
100
- base_model_url = "https://huggingface.co/broyang/hentaidigitalart_v20/blob/main/realcartoon3d_v15.safetensors"
101
- pipe = StableDiffusionControlNetPipeline.from_single_file(
102
- base_model_url,
103
- safety_checker=None,
104
- controlnet=controlnet,
105
- scheduler=scheduler,
106
- torch_dtype=torch.float16,
107
- )
108
- pipe.load_textual_inversion("broyang/hentaidigitalart_v20", weight_name="EasyNegativeV2.safetensors", token="EasyNegativeV2")
109
- pipe.load_textual_inversion("broyang/hentaidigitalart_v20", weight_name="badhandv4.pt", token="badhandv4")
110
- pipe.load_textual_inversion("broyang/hentaidigitalart_v20", weight_name="HDA_Ahegao.pt", token="HDA_Ahegao")
111
- pipe.load_textual_inversion("broyang/hentaidigitalart_v20", weight_name="HDA_Bondage.pt", token="HDA_Bondage")
112
- pipe.load_textual_inversion("broyang/hentaidigitalart_v20", weight_name="HDA_pet_play.pt", token="HDA_pet_play")
113
- pipe.load_textual_inversion("broyang/hentaidigitalart_v20", weight_name="fcNeg-neg.pt", token="fcNeg-neg")
114
- pipe.load_textual_inversion("broyang/hentaidigitalart_v20", weight_name="HDA_unconventional maid.pt", token="HDA_unconventional_maid")
115
- pipe.load_textual_inversion("broyang/hentaidigitalart_v20", weight_name="HDA_NakedHoodie.pt", token="HDA_NakedHoodie")
116
- pipe.load_textual_inversion("broyang/hentaidigitalart_v20", weight_name="HDA_NunDress.pt", token="HDA_NunDress")
117
- pipe.load_textual_inversion("broyang/hentaidigitalart_v20", weight_name="HDA_Shibari.pt", token="HDA_Shibari")
118
- pipe.to("cuda")
119
- print("---------------Loaded controlnet pipeline---------------")
120
-
121
- @spaces.GPU(duration=11)
122
- @torch.inference_mode()
123
- def process_image(
124
- image,
125
- prompt,
126
- a_prompt,
127
- n_prompt,
128
- num_images,
129
- image_resolution,
130
- preprocess_resolution,
131
- num_steps,
132
- guidance_scale,
133
- seed,
134
- ):
135
- initialize_models()
136
- preprocessor.load("NormalBae")
137
- control_image = preprocessor(
138
- image=image,
139
- image_resolution=image_resolution,
140
- detect_resolution=preprocess_resolution,
141
- )
142
- custom_prompt = str(get_prompt(prompt, a_prompt))
143
- negative_prompt = str(n_prompt)
144
- global compiled
145
- generator = torch.cuda.manual_seed(seed)
146
- if not compiled:
147
- print("-----------------------------------Not Compiled-----------------------------------")
148
- compiled = True
149
- start = time.time()
150
- results = pipe(
151
- prompt=custom_prompt,
152
- negative_prompt=negative_prompt,
153
- guidance_scale=guidance_scale,
154
- num_images_per_prompt=num_images,
155
- num_inference_steps=num_steps,
156
- generator=generator,
157
- image=control_image,
158
- ).images[0]
159
- print(f"Inference done in: {time.time() - start:.2f} seconds")
160
-
161
- timestamp = int(time.time())
162
- img_path = f"{timestamp}.jpg"
163
- results_path = f"{timestamp}_out.jpg"
164
- imageio.imsave(img_path, image)
165
- results.save(results_path)
166
-
167
- api.upload_file(
168
- path_or_fileobj=img_path,
169
- path_in_repo=img_path,
170
- repo_id="broyang/anime-ai-outputs",
171
- repo_type="dataset",
172
- token=API_KEY,
173
- run_as_future=True,
174
- )
175
- api.upload_file(
176
- path_or_fileobj=results_path,
177
- path_in_repo=results_path,
178
- repo_id="broyang/anime-ai-outputs",
179
- repo_type="dataset",
180
- token=API_KEY,
181
- run_as_future=True,
182
- )
183
-
184
- conditionally_manage_memory()
185
-
186
- results.save("temp_image.png")
187
- return results
188
-
189
- def main():
190
- prod = True
191
- show_options = True
192
- if prod:
193
- show_options = False
194
-
195
- print("CUDA version:", torch.version.cuda)
196
- print("loading pipe")
197
-
198
- css = """
199
- h1 {
200
- text-align: center;
201
- display:block;
202
- }
203
- h2 {
204
- text-align: center;
205
- display:block;
206
- }
207
- h3 {
208
- text-align: center;
209
- display:block;
210
- }
211
- footer {visibility: hidden}
212
- """
213
- with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
214
- with gr.Row():
215
- with gr.Accordion("Advanced options", open=show_options, visible=show_options):
216
- num_images = gr.Slider(
217
- label="Images", minimum=1, maximum=MAX_NUM_IMAGES, value=1, step=1
218
- )
219
- image_resolution = gr.Slider(
220
- label="Image resolution",
221
- minimum=256,
222
- maximum=1024,
223
- value=768,
224
- step=256,
225
- )
226
- preprocess_resolution = gr.Slider(
227
- label="Preprocess resolution",
228
- minimum=128,
229
- maximum=1024,
230
- value=768,
231
- step=1,
232
- )
233
- num_steps = gr.Slider(
234
- label="Number of steps", minimum=1, maximum=100, value=12, step=1
235
- )
236
- guidance_scale = gr.Slider(
237
- label="Guidance scale", minimum=0.1, maximum=30.0, value=5.5, step=0.1
238
- )
239
- seed = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=0)
240
- randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
241
- a_prompt = gr.Textbox(
242
- label="Additional prompt",
243
- value = ""
244
- )
245
- n_prompt = gr.Textbox(
246
- label="Negative prompt",
247
- value="EasyNegativeV2, fcNeg, (badhandv4:1.4), (worst quality, low quality, bad quality, normal quality:2.0), (bad hands, missing fingers, extra fingers:2.0)",
248
- )
249
- with gr.Column():
250
- prompt = gr.Textbox(
251
- label="Description",
252
- placeholder="Leave empty for something spicy 👀",
253
- )
254
- with gr.Row():
255
- with gr.Column():
256
- image = gr.Image(
257
- label="Input",
258
- sources=["upload"],
259
- show_label=True,
260
- format="webp",
261
- )
262
- with gr.Column():
263
- run_button = gr.Button(value="Use this one", size=["lg"], visible=False)
264
- with gr.Column():
265
- result = gr.Image(
266
- label="Anime AI",
267
- interactive=False,
268
- format="webp",
269
- visible = True,
270
- show_share_button= False,
271
- )
272
- with gr.Column():
273
- use_ai_button = gr.Button(value="Use this one", size=["lg"], visible=False)
274
- config = [
275
- image,
276
- prompt,
277
- a_prompt,
278
- n_prompt,
279
- num_images,
280
- image_resolution,
281
- preprocess_resolution,
282
- num_steps,
283
- guidance_scale,
284
- seed,
285
- ]
286
-
287
- @spaces.GPU(duration=11)
288
- @torch.inference_mode()
289
- @gr.on(triggers=[image.upload], inputs=config, outputs=[result])
290
- def auto_process_image(image, prompt, a_prompt, n_prompt, num_images, image_resolution, preprocess_resolution, num_steps, guidance_scale, seed):
291
- return process_image(image, prompt, a_prompt, n_prompt, num_images, image_resolution, preprocess_resolution, num_steps, guidance_scale, seed)
292
-
293
- @gr.on(triggers=[image.upload], inputs=None, outputs=[use_ai_button, run_button])
294
- def turn_buttons_off():
295
- return gr.update(visible=False), gr.update(visible=False)
296
-
297
- @gr.on(triggers=[use_ai_button.click], inputs=None, outputs=[use_ai_button, run_button])
298
- def turn_buttons_off():
299
- return gr.update(visible=False), gr.update(visible=False)
300
-
301
- @gr.on(triggers=[run_button.click], inputs=None, outputs=[use_ai_button, run_button])
302
- def turn_buttons_off():
303
- return gr.update(visible=False), gr.update(visible=False)
304
-
305
- @gr.on(triggers=[result.change], inputs=None, outputs=[use_ai_button, run_button])
306
- def turn_buttons_on():
307
- return gr.update(visible=True), gr.update(visible=True)
308
-
309
- with gr.Row():
310
- helper_text = gr.Markdown("## Tap and hold (on mobile) to save the image.", visible=True)
311
-
312
- prompt.submit(
313
- fn=randomize_seed_fn,
314
- inputs=[seed, randomize_seed],
315
- outputs=seed,
316
- queue=False,
317
- api_name=False,
318
- show_progress="none",
319
- ).then(
320
- fn=auto_process_image,
321
- inputs=config,
322
- outputs=result,
323
- api_name=False,
324
- show_progress="minimal",
325
- )
326
-
327
- run_button.click(
328
- fn=randomize_seed_fn,
329
- inputs=[seed, randomize_seed],
330
- outputs=seed,
331
- queue=False,
332
- api_name=False,
333
- show_progress="none",
334
- ).then(
335
- fn=auto_process_image,
336
- inputs=config,
337
- outputs=result,
338
- show_progress="minimal",
339
- )
340
-
341
- def update_config():
342
- try:
343
- print("Updating image to AI Temp Image")
344
- ai_temp_image = Image.open("temp_image.png")
345
- return ai_temp_image
346
- except FileNotFoundError:
347
- print("No AI Image Available")
348
- return None
349
-
350
- use_ai_button.click(
351
- fn=randomize_seed_fn,
352
- inputs=[seed, randomize_seed],
353
- outputs=seed,
354
- queue=False,
355
- api_name=False,
356
- show_progress="none",
357
- ).then(
358
- fn=lambda _: update_config(),
359
- inputs=[image],
360
- outputs=image,
361
- show_progress="minimal",
362
- ).then(
363
- fn=auto_process_image,
364
- inputs=[image, prompt, a_prompt, n_prompt, num_images, image_resolution, preprocess_resolution, num_steps, guidance_scale, seed],
365
- outputs=result,
366
- show_progress="minimal",
367
- )
368
-
369
- demo.launch()
370
-
371
- if __name__ == "__main__":
372
- pr = cProfile.Profile()
373
- pr.enable()
374
- main()
375
- pr.disable()
376
-
377
- s = io.StringIO()
378
- sortby = 'cumulative'
379
- ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
380
- ps.print_stats()
381
- print(s.getvalue())