nyanko7/sd-diffusers-webui
141
1import random2import tempfile3import time4import gradio as gr5import numpy as np6import torch7import math8import re9 10from gradio import inputs11from diffusers import (12 AutoencoderKL,13 DDIMScheduler,14 UNet2DConditionModel,15)16from modules.model import (17 CrossAttnProcessor,18 StableDiffusionPipeline,19)20from torchvision import transforms21from transformers import CLIPTokenizer, CLIPTextModel22from PIL import Image23from pathlib import Path24from safetensors.torch import load_file25import modules.safe as _26from modules.lora import LoRANetwork27 28models = [29 ("AbyssOrangeMix2", "Korakoe/AbyssOrangeMix2-HF", 2),30 ("Pastal Mix", "JamesFlare/pastel-mix", 2),31 ("Basil Mix", "nuigurumi/basil_mix", 2)32]33 34keep_vram = ["Korakoe/AbyssOrangeMix2-HF", "andite/pastel-mix"]35base_name, base_model, clip_skip = models[0]36 37samplers_k_diffusion = [38 ("Euler a", "sample_euler_ancestral", {}),39 ("Euler", "sample_euler", {}),40 ("LMS", "sample_lms", {}),41 ("Heun", "sample_heun", {}),42 ("DPM2", "sample_dpm_2", {"discard_next_to_last_sigma": True}),43 ("DPM2 a", "sample_dpm_2_ancestral", {"discard_next_to_last_sigma": True}),44 ("DPM++ 2S a", "sample_dpmpp_2s_ancestral", {}),45 ("DPM++ 2M", "sample_dpmpp_2m", {}),46 ("DPM++ SDE", "sample_dpmpp_sde", {}),47 ("LMS Karras", "sample_lms", {"scheduler": "karras"}),48 ("DPM2 Karras", "sample_dpm_2", {"scheduler": "karras", "discard_next_to_last_sigma": True}),49 ("DPM2 a Karras", "sample_dpm_2_ancestral", {"scheduler": "karras", "discard_next_to_last_sigma": True}),50 ("DPM++ 2S a Karras", "sample_dpmpp_2s_ancestral", {"scheduler": "karras"}),51 ("DPM++ 2M Karras", "sample_dpmpp_2m", {"scheduler": "karras"}),52 ("DPM++ SDE Karras", "sample_dpmpp_sde", {"scheduler": "karras"}),53]54 55# samplers_diffusers = [56# ("DDIMScheduler", "diffusers.schedulers.DDIMScheduler", {})57# ("DDPMScheduler", "diffusers.schedulers.DDPMScheduler", {})58# ("DEISMultistepScheduler", "diffusers.schedulers.DEISMultistepScheduler", {})59# ]60 61start_time = time.time()62timeout = 9063 64scheduler = DDIMScheduler.from_pretrained(65 base_model,66 subfolder="scheduler",67)68vae = AutoencoderKL.from_pretrained(69 "stabilityai/sd-vae-ft-ema", 70 torch_dtype=torch.float1671)72text_encoder = CLIPTextModel.from_pretrained(73 base_model,74 subfolder="text_encoder",75 torch_dtype=torch.float16,76)77tokenizer = CLIPTokenizer.from_pretrained(78 base_model,79 subfolder="tokenizer",80 torch_dtype=torch.float16,81)82unet = UNet2DConditionModel.from_pretrained(83 base_model,84 subfolder="unet",85 torch_dtype=torch.float16,86)87pipe = StableDiffusionPipeline(88 text_encoder=text_encoder,89 tokenizer=tokenizer,90 unet=unet,91 vae=vae,92 scheduler=scheduler,93)94 95unet.set_attn_processor(CrossAttnProcessor)96pipe.setup_text_encoder(clip_skip, text_encoder)97if torch.cuda.is_available():98 pipe = pipe.to("cuda")99 100def get_model_list():101 return models102 103te_cache = {104 base_model: text_encoder105}106 107unet_cache = {108 base_model: unet109}110 111lora_cache = {112 base_model: LoRANetwork(text_encoder, unet)113}114 115te_base_weight_length = text_encoder.get_input_embeddings().weight.data.shape[0]116original_prepare_for_tokenization = tokenizer.prepare_for_tokenization117current_model = base_model118 119def setup_model(name, lora_state=None, lora_scale=1.0):120 global pipe, current_model121 122 keys = [k[0] for k in models]123 model = models[keys.index(name)][1]124 if model not in unet_cache:125 unet = UNet2DConditionModel.from_pretrained(model, subfolder="unet", torch_dtype=torch.float16)126 text_encoder = CLIPTextModel.from_pretrained(model, subfolder="text_encoder", torch_dtype=torch.float16)127 128 unet_cache[model] = unet129 te_cache[model] = text_encoder130 lora_cache[model] = LoRANetwork(text_encoder, unet)131 132 if current_model != model:133 if current_model not in keep_vram:134 # offload current model135 unet_cache[current_model].to("cpu")136 te_cache[current_model].to("cpu")137 lora_cache[current_model].to("cpu")138 current_model = model139 140 local_te, local_unet, local_lora, = te_cache[model], unet_cache[model], lora_cache[model]141 local_unet.set_attn_processor(CrossAttnProcessor())142 local_lora.reset()143 clip_skip = models[keys.index(name)][2]144 145 if torch.cuda.is_available():146 local_unet.to("cuda")147 local_te.to("cuda")148 149 if lora_state is not None and lora_state != "":150 local_lora.load(lora_state, lora_scale)151 local_lora.to(local_unet.device, dtype=local_unet.dtype)152 153 pipe.text_encoder, pipe.unet = local_te, local_unet154 pipe.setup_unet(local_unet)155 pipe.tokenizer.prepare_for_tokenization = original_prepare_for_tokenization156 pipe.tokenizer.added_tokens_encoder = {}157 pipe.tokenizer.added_tokens_decoder = {}158 pipe.setup_text_encoder(clip_skip, local_te)159 return pipe160 161 162def error_str(error, title="Error"):163 return (164 f"""#### {title}165 {error}"""166 if error167 else ""168 )169 170def make_token_names(embs):171 all_tokens = []172 for name, vec in embs.items():173 tokens = [f'emb-{name}-{i}' for i in range(len(vec))]174 all_tokens.append(tokens)175 return all_tokens176 177def setup_tokenizer(tokenizer, embs):178 reg_match = [re.compile(fr"(?:^|(?<=\s|,)){k}(?=,|\s|$)") for k in embs.keys()]179 clip_keywords = [' '.join(s) for s in make_token_names(embs)]180 181 def parse_prompt(prompt: str):182 for m, v in zip(reg_match, clip_keywords):183 prompt = m.sub(v, prompt)184 return prompt185 186 def prepare_for_tokenization(self, text: str, is_split_into_words: bool = False, **kwargs):187 text = parse_prompt(text)188 r = original_prepare_for_tokenization(text, is_split_into_words, **kwargs)189 return r190 tokenizer.prepare_for_tokenization = prepare_for_tokenization.__get__(tokenizer, CLIPTokenizer)191 return [t for sublist in make_token_names(embs) for t in sublist]192 193 194def convert_size(size_bytes):195 if size_bytes == 0:196 return "0B"197 size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")198 i = int(math.floor(math.log(size_bytes, 1024)))199 p = math.pow(1024, i)200 s = round(size_bytes / p, 2)201 return "%s %s" % (s, size_name[i])202 203def inference(204 prompt,205 guidance,206 steps,207 width=512,208 height=512,209 seed=0,210 neg_prompt="",211 state=None,212 g_strength=0.4,213 img_input=None,214 i2i_scale=0.5,215 hr_enabled=False,216 hr_method="Latent",217 hr_scale=1.5,218 hr_denoise=0.8,219 sampler="DPM++ 2M Karras",220 embs=None,221 model=None,222 lora_state=None,223 lora_scale=None,224):225 if seed is None or seed == 0:226 seed = random.randint(0, 2147483647)227 228 pipe = setup_model(model, lora_state, lora_scale)229 generator = torch.Generator("cuda").manual_seed(int(seed))230 start_time = time.time()231 232 sampler_name, sampler_opt = None, None233 for label, funcname, options in samplers_k_diffusion:234 if label == sampler:235 sampler_name, sampler_opt = funcname, options236 237 tokenizer, text_encoder = pipe.tokenizer, pipe.text_encoder238 if embs is not None and len(embs) > 0:239 ti_embs = {}240 for name, file in embs.items():241 if str(file).endswith(".pt"):242 loaded_learned_embeds = torch.load(file, map_location="cpu")243 else:244 loaded_learned_embeds = load_file(file, device="cpu")245 loaded_learned_embeds = loaded_learned_embeds["string_to_param"]["*"] if "string_to_param" in loaded_learned_embeds else loaded_learned_embeds246 ti_embs[name] = loaded_learned_embeds247 248 if len(ti_embs) > 0:249 tokens = setup_tokenizer(tokenizer, ti_embs)250 added_tokens = tokenizer.add_tokens(tokens)251 delta_weight = torch.cat([val for val in ti_embs.values()], dim=0)252 253 assert added_tokens == delta_weight.shape[0]254 text_encoder.resize_token_embeddings(len(tokenizer))255 token_embeds = text_encoder.get_input_embeddings().weight.data256 token_embeds[-delta_weight.shape[0]:] = delta_weight257 258 config = {259 "negative_prompt": neg_prompt,260 "num_inference_steps": int(steps),261 "guidance_scale": guidance,262 "generator": generator,263 "sampler_name": sampler_name,264 "sampler_opt": sampler_opt,265 "pww_state": state,266 "pww_attn_weight": g_strength,267 "start_time": start_time,268 "timeout": timeout,269 }270 271 if img_input is not None:272 ratio = min(height / img_input.height, width / img_input.width)273 img_input = img_input.resize(274 (int(img_input.width * ratio), int(img_input.height * ratio)), Image.LANCZOS275 )276 result = pipe.img2img(prompt, image=img_input, strength=i2i_scale, **config)277 elif hr_enabled:278 result = pipe.txt2img(279 prompt,280 width=width,281 height=height,282 upscale=True,283 upscale_x=hr_scale,284 upscale_denoising_strength=hr_denoise,285 **config,286 **latent_upscale_modes[hr_method],287 )288 else:289 result = pipe.txt2img(prompt, width=width, height=height, **config)290 291 end_time = time.time()292 vram_free, vram_total = torch.cuda.mem_get_info()293 print(f"done: model={model}, res={width}x{height}, step={steps}, time={round(end_time-start_time, 2)}s, vram_alloc={convert_size(vram_total-vram_free)}/{convert_size(vram_total)}")294 return gr.Image.update(result[0][0], label=f"Initial Seed: {seed}")295 296 297color_list = []298 299 300def get_color(n):301 for _ in range(n - len(color_list)):302 color_list.append(tuple(np.random.random(size=3) * 256))303 return color_list304 305 306def create_mixed_img(current, state, w=512, h=512):307 w, h = int(w), int(h)308 image_np = np.full([h, w, 4], 255)309 if state is None:310 state = {}311 312 colors = get_color(len(state))313 idx = 0314 315 for key, item in state.items():316 if item["map"] is not None:317 m = item["map"] < 255318 alpha = 150319 if current == key:320 alpha = 200321 image_np[m] = colors[idx] + (alpha,)322 idx += 1323 324 return image_np325 326 327# width.change(apply_new_res, inputs=[width, height, global_stats], outputs=[global_stats, sp, rendered])328def apply_new_res(w, h, state):329 w, h = int(w), int(h)330 331 for key, item in state.items():332 if item["map"] is not None:333 item["map"] = resize(item["map"], w, h)334 335 update_img = gr.Image.update(value=create_mixed_img("", state, w, h))336 return state, update_img337 338 339def detect_text(text, state, width, height):340 341 if text is None or text == "":342 return None, None, gr.Radio.update(value=None), None343 344 t = text.split(",")345 new_state = {}346 347 for item in t:348 item = item.strip()349 if item == "":350 continue351 if state is not None and item in state:352 new_state[item] = {353 "map": state[item]["map"],354 "weight": state[item]["weight"],355 "mask_outsides": state[item]["mask_outsides"],356 }357 else:358 new_state[item] = {359 "map": None,360 "weight": 0.5,361 "mask_outsides": False362 }363 update = gr.Radio.update(choices=[key for key in new_state.keys()], value=None)364 update_img = gr.update(value=create_mixed_img("", new_state, width, height))365 update_sketch = gr.update(value=None, interactive=False)366 return new_state, update_sketch, update, update_img367 368 369def resize(img, w, h):370 trs = transforms.Compose(371 [372 transforms.ToPILImage(),373 transforms.Resize(min(h, w)),374 transforms.CenterCrop((h, w)),375 ]376 )377 result = np.array(trs(img), dtype=np.uint8)378 return result379 380 381def switch_canvas(entry, state, width, height):382 if entry == None:383 return None, 0.5, False, create_mixed_img("", state, width, height)384 385 return (386 gr.update(value=None, interactive=True),387 gr.update(value=state[entry]["weight"] if entry in state else 0.5),388 gr.update(value=state[entry]["mask_outsides"] if entry in state else False),389 create_mixed_img(entry, state, width, height),390 )391 392 393def apply_canvas(selected, draw, state, w, h):394 if selected in state:395 w, h = int(w), int(h)396 state[selected]["map"] = resize(draw, w, h)397 return state, gr.Image.update(value=create_mixed_img(selected, state, w, h))398 399 400def apply_weight(selected, weight, state):401 if selected in state:402 state[selected]["weight"] = weight403 return state404 405 406def apply_option(selected, mask, state):407 if selected in state:408 state[selected]["mask_outsides"] = mask409 return state410 411 412# sp2, radio, width, height, global_stats413def apply_image(image, selected, w, h, strgength, mask, state):414 if selected in state:415 state[selected] = {416 "map": resize(image, w, h), 417 "weight": strgength, 418 "mask_outsides": mask419 }420 421 return state, gr.Image.update(value=create_mixed_img(selected, state, w, h))422 423 424# [ti_state, lora_state, ti_vals, lora_vals, uploads]425def add_net(files, ti_state, lora_state):426 if files is None:427 return ti_state, "", lora_state, None428 429 for file in files:430 item = Path(file.name)431 stripedname = str(item.stem).strip()432 if item.suffix == ".pt":433 state_dict = torch.load(file.name, map_location="cpu")434 else:435 state_dict = load_file(file.name, device="cpu")436 if any("lora" in k for k in state_dict.keys()):437 lora_state = file.name438 else:439 ti_state[stripedname] = file.name440 441 return (442 ti_state,443 lora_state,444 gr.Text.update(f"{[key for key in ti_state.keys()]}"),445 gr.Text.update(f"{lora_state}"),446 gr.Files.update(value=None),447 )448 449 450# [ti_state, lora_state, ti_vals, lora_vals, uploads]451def clean_states(ti_state, lora_state):452 return (453 dict(),454 None,455 gr.Text.update(f""),456 gr.Text.update(f""),457 gr.File.update(value=None),458 )459 460 461latent_upscale_modes = {462 "Latent": {"upscale_method": "bilinear", "upscale_antialias": False},463 "Latent (antialiased)": {"upscale_method": "bilinear", "upscale_antialias": True},464 "Latent (bicubic)": {"upscale_method": "bicubic", "upscale_antialias": False},465 "Latent (bicubic antialiased)": {466 "upscale_method": "bicubic",467 "upscale_antialias": True,468 },469 "Latent (nearest)": {"upscale_method": "nearest", "upscale_antialias": False},470 "Latent (nearest-exact)": {471 "upscale_method": "nearest-exact",472 "upscale_antialias": False,473 },474}475 476css = """477.finetuned-diffusion-div div{478 display:inline-flex;479 align-items:center;480 gap:.8rem;481 font-size:1.75rem;482 padding-top:2rem;483}484.finetuned-diffusion-div div h1{485 font-weight:900;486 margin-bottom:7px487}488.finetuned-diffusion-div p{489 margin-bottom:10px;490 font-size:94%491}492.box {493 float: left;494 height: 20px;495 width: 20px;496 margin-bottom: 15px;497 border: 1px solid black;498 clear: both;499}500a{501 text-decoration:underline502}503.tabs{504 margin-top:0;505 margin-bottom:0506}507#gallery{508 min-height:20rem509}510.no-border {511 border: none !important;512}513 """514with gr.Blocks(css=css) as demo:515 gr.HTML(516 f"""517 <div class="finetuned-diffusion-div">518 <div>519 <h1>Demo for diffusion models</h1>520 </div>521 <p>Hso @ nyanko.sketch2img.gradio</p>522 </div>523 """524 )525 global_stats = gr.State(value={})526 527 with gr.Row():528 529 with gr.Column(scale=55):530 model = gr.Dropdown(531 choices=[k[0] for k in get_model_list()],532 label="Model",533 value=base_name,534 )535 image_out = gr.Image(height=512)536 # gallery = gr.Gallery(537 # label="Generated images", show_label=False, elem_id="gallery"538 # ).style(grid=[1], height="auto")539 540 with gr.Column(scale=45):541 542 with gr.Group():543 544 with gr.Row():545 with gr.Column(scale=70):546 547 prompt = gr.Textbox(548 label="Prompt",549 value="loli cat girl, blue eyes, flat chest, solo, long messy silver hair, blue capelet, cat ears, cat tail, upper body",550 show_label=True,551 max_lines=4,552 placeholder="Enter prompt.",553 )554 neg_prompt = gr.Textbox(555 label="Negative Prompt",556 value="bad quality, low quality, jpeg artifact, cropped",557 show_label=True,558 max_lines=4,559 placeholder="Enter negative prompt.",560 )561 562 generate = gr.Button(value="Generate").style(563 rounded=(False, True, True, False)564 )565 566 with gr.Tab("Options"):567 568 with gr.Group():569 570 # n_images = gr.Slider(label="Images", value=1, minimum=1, maximum=4, step=1)571 with gr.Row():572 guidance = gr.Slider(573 label="Guidance scale", value=7.5, maximum=15574 )575 steps = gr.Slider(576 label="Steps", value=25, minimum=2, maximum=50, step=1577 )578 579 with gr.Row():580 width = gr.Slider(581 label="Width", value=512, minimum=64, maximum=768, step=64582 )583 height = gr.Slider(584 label="Height", value=512, minimum=64, maximum=768, step=64585 )586 587 sampler = gr.Dropdown(588 value="DPM++ 2M Karras",589 label="Sampler",590 choices=[s[0] for s in samplers_k_diffusion],591 )592 seed = gr.Number(label="Seed (0 = random)", value=0)593 594 with gr.Tab("Image to image"):595 with gr.Group():596 597 inf_image = gr.Image(598 label="Image", height=256, tool="editor", type="pil"599 )600 inf_strength = gr.Slider(601 label="Transformation strength",602 minimum=0,603 maximum=1,604 step=0.01,605 value=0.5,606 )607 608 def res_cap(g, w, h, x):609 if g:610 return f"Enable upscaler: {w}x{h} to {int(w*x)}x{int(h*x)}"611 else:612 return "Enable upscaler"613 614 with gr.Tab("Hires fix"):615 with gr.Group():616 617 hr_enabled = gr.Checkbox(label="Enable upscaler", value=False)618 hr_method = gr.Dropdown(619 [key for key in latent_upscale_modes.keys()],620 value="Latent",621 label="Upscale method",622 )623 hr_scale = gr.Slider(624 label="Upscale factor",625 minimum=1.0,626 maximum=1.5,627 step=0.1,628 value=1.2,629 )630 hr_denoise = gr.Slider(631 label="Denoising strength",632 minimum=0.0,633 maximum=1.0,634 step=0.1,635 value=0.8,636 )637 638 hr_scale.change(639 lambda g, x, w, h: gr.Checkbox.update(640 label=res_cap(g, w, h, x)641 ),642 inputs=[hr_enabled, hr_scale, width, height],643 outputs=hr_enabled,644 queue=False,645 )646 hr_enabled.change(647 lambda g, x, w, h: gr.Checkbox.update(648 label=res_cap(g, w, h, x)649 ),650 inputs=[hr_enabled, hr_scale, width, height],651 outputs=hr_enabled,652 queue=False,653 )654 655 with gr.Tab("Embeddings/Loras"):656 657 ti_state = gr.State(dict())658 lora_state = gr.State()659 660 with gr.Group():661 with gr.Row():662 with gr.Column(scale=90):663 ti_vals = gr.Text(label="Loaded embeddings")664 665 with gr.Row():666 with gr.Column(scale=90):667 lora_vals = gr.Text(label="Loaded loras")668 669 with gr.Row():670 671 uploads = gr.Files(label="Upload new embeddings/lora")672 673 with gr.Column():674 lora_scale = gr.Slider(675 label="Lora scale",676 minimum=0,677 maximum=2,678 step=0.01,679 value=1.0,680 )681 btn = gr.Button(value="Upload")682 btn_del = gr.Button(value="Reset")683 684 btn.click(685 add_net,686 inputs=[uploads, ti_state, lora_state],687 outputs=[ti_state, lora_state, ti_vals, lora_vals, uploads],688 queue=False,689 )690 btn_del.click(691 clean_states,692 inputs=[ti_state, lora_state],693 outputs=[ti_state, lora_state, ti_vals, lora_vals, uploads],694 queue=False,695 )696 697 # error_output = gr.Markdown()698 699 gr.HTML(700 f"""701 <div class="finetuned-diffusion-div">702 <div>703 <h1>Paint with words</h1>704 </div>705 <p>706 Will use the following formula: w = scale * token_weight_martix * log(1 + sigma) * max(qk).707 </p>708 </div>709 """710 )711 712 with gr.Row():713 714 with gr.Column(scale=55):715 716 rendered = gr.Image(717 invert_colors=True,718 source="canvas",719 interactive=False,720 image_mode="RGBA",721 )722 723 with gr.Column(scale=45):724 725 with gr.Group():726 with gr.Row():727 with gr.Column(scale=70):728 g_strength = gr.Slider(729 label="Weight scaling",730 minimum=0,731 maximum=0.8,732 step=0.01,733 value=0.4,734 )735 736 text = gr.Textbox(737 lines=2,738 interactive=True,739 label="Token to Draw: (Separate by comma)",740 )741 742 radio = gr.Radio([], label="Tokens")743 744 sk_update = gr.Button(value="Update").style(745 rounded=(False, True, True, False)746 )747 748 # g_strength.change(lambda b: gr.update(f"Scaled additional attn: $w = {b} \log (1 + \sigma) \std (Q^T K)$."), inputs=g_strength, outputs=[g_output])749 750 with gr.Tab("SketchPad"):751 752 sp = gr.Image(753 image_mode="L",754 tool="sketch",755 source="canvas",756 interactive=False,757 )758 759 mask_outsides = gr.Checkbox(760 label="Mask other areas", 761 value=False762 )763 764 strength = gr.Slider(765 label="Token strength",766 minimum=0,767 maximum=0.8,768 step=0.01,769 value=0.5,770 )771 772 773 sk_update.click(774 detect_text,775 inputs=[text, global_stats, width, height],776 outputs=[global_stats, sp, radio, rendered],777 queue=False,778 )779 radio.change(780 switch_canvas,781 inputs=[radio, global_stats, width, height],782 outputs=[sp, strength, mask_outsides, rendered],783 queue=False,784 )785 sp.edit(786 apply_canvas,787 inputs=[radio, sp, global_stats, width, height],788 outputs=[global_stats, rendered],789 queue=False,790 )791 strength.change(792 apply_weight,793 inputs=[radio, strength, global_stats],794 outputs=[global_stats],795 queue=False,796 )797 mask_outsides.change(798 apply_option,799 inputs=[radio, mask_outsides, global_stats],800 outputs=[global_stats],801 queue=False,802 )803 804 with gr.Tab("UploadFile"):805 806 sp2 = gr.Image(807 image_mode="L",808 source="upload",809 shape=(512, 512),810 )811 812 mask_outsides2 = gr.Checkbox(813 label="Mask other areas", 814 value=False,815 )816 817 strength2 = gr.Slider(818 label="Token strength",819 minimum=0,820 maximum=0.8,821 step=0.01,822 value=0.5,823 )824 825 apply_style = gr.Button(value="Apply")826 apply_style.click(827 apply_image,828 inputs=[sp2, radio, width, height, strength2, mask_outsides2, global_stats],829 outputs=[global_stats, rendered],830 queue=False,831 )832 833 width.change(834 apply_new_res,835 inputs=[width, height, global_stats],836 outputs=[global_stats, rendered],837 queue=False,838 )839 height.change(840 apply_new_res,841 inputs=[width, height, global_stats],842 outputs=[global_stats, rendered],843 queue=False,844 )845 846 # color_stats = gr.State(value={})847 # text.change(detect_color, inputs=[sp, text, color_stats], outputs=[color_stats, rendered])848 # sp.change(detect_color, inputs=[sp, text, color_stats], outputs=[color_stats, rendered])849 850 inputs = [851 prompt,852 guidance,853 steps,854 width,855 height,856 seed,857 neg_prompt,858 global_stats,859 g_strength,860 inf_image,861 inf_strength,862 hr_enabled,863 hr_method,864 hr_scale,865 hr_denoise,866 sampler,867 ti_state,868 model,869 lora_state,870 lora_scale,871 ]872 outputs = [image_out]873 prompt.submit(inference, inputs=inputs, outputs=outputs)874 generate.click(inference, inputs=inputs, outputs=outputs)875 876print(f"Space built in {time.time() - start_time:.2f} seconds")877# demo.launch(share=True)878demo.launch(enable_queue=True, server_name="0.0.0.0", server_port=7860)879 