import os import gradio as gr import argparse import numpy as np import torch import einops import copy import math import time import random import spaces import re import uuid from gradio_imageslider import ImageSlider from PIL import Image from BOOXEL.util import HWC3, upscale_image, fix_resize, convert_dtype, create_BOOXEL_model, load_QF_ckpt from huggingface_hub import hf_hub_download from pillow_heif import register_heif_opener register_heif_opener() max_64_bit_int = np.iinfo(np.int32).max hf_hub_download(repo_id="laion/CLIP-ViT-bigG-14-laion2B-39B-b160k", filename="open_clip_pytorch_model.bin", local_dir="laion_CLIP-ViT-bigG-14-laion2B-39B-b160k") hf_hub_download(repo_id="ckpt/sd_xl_base_1.0", filename="sd_xl_base_1.0_0.9vae.safetensors", local_dir="ckpt_sd_xl_base_1.0") hf_hub_download(repo_id="yanranxiaoxi/booxel", filename="BOOXEL-v0.F.ckpt", local_dir="yanranxiaoxi_booxel", token=os.environ.get('MODEL_ACCESS_TOKEN')) hf_hub_download(repo_id="yanranxiaoxi/booxel", filename="BOOXEL-v0.Q.ckpt", local_dir="yanranxiaoxi_booxel", token=os.environ.get('MODEL_ACCESS_TOKEN')) hf_hub_download(repo_id="RunDiffusion/Juggernaut-XL-Lightning", filename="Juggernaut_RunDiffusionPhoto2_Lightning_4Steps.safetensors", local_dir="RunDiffusion_Juggernaut-XL-Lightning") parser = argparse.ArgumentParser() parser.add_argument("--opt", type=str, default='options/BOOXEL_v0.yaml') parser.add_argument("--ip", type=str, default='127.0.0.1') parser.add_argument("--port", type=int, default='6688') parser.add_argument("--no_llava", action='store_true', default=True)#False parser.add_argument("--use_image_slider", action='store_true', default=False)#False parser.add_argument("--log_history", action='store_true', default=False) parser.add_argument("--loading_half_params", action='store_true', default=False)#False parser.add_argument("--use_tile_vae", action='store_true', default=True)#False parser.add_argument("--encoder_tile_size", type=int, default=512) parser.add_argument("--decoder_tile_size", type=int, default=64) parser.add_argument("--load_8bit_llava", action='store_true', default=False) args = parser.parse_args() BOOXEL_device = 'cpu' # 加载 BOOXEL model, default_setting = create_BOOXEL_model(args.opt, BOOXEL_sign='Q', load_default_setting=True) if args.loading_half_params: model = model.half() if args.use_tile_vae: model.init_tile_vae(encoder_tile_size=args.encoder_tile_size, decoder_tile_size=args.decoder_tile_size) model = model.to(BOOXEL_device) model.first_stage_model.denoise_encoder_s1 = copy.deepcopy(model.first_stage_model.denoise_encoder) model.current_model = 'v0-Q' ckpt_Q, ckpt_F = load_QF_ckpt(args.opt) def check_upload(input_image): if input_image is None: raise gr.Error("请提供要处理的图像。") return gr.update(visible = True) def update_seed(is_randomize_seed, seed): if is_randomize_seed: return random.randint(0, max_64_bit_int) return seed def reset(): return [ None, 0, None, None, "电影级,高对比度,高度精细,使用哈苏相机拍摄,超精细照片,逼真的最大细节,32K,调色,超高清,极致的细节,皮肤毛孔细节,超清晰度,完美无变形。", "绘画,油画,插图,绘图,艺术,素描,动漫,卡通,CG 风格,3D 渲染,虚幻引擎,模糊,混色,不清晰,怪异纹理,丑陋,肮脏,凌乱,质量最差,质量低,框架,水印,签名,JPEG 伪影,变形,低分辨率,过度平滑", 1, 1024, 1, 2, 50, -1.0, 1., default_setting.s_cfg_Quality if torch.cuda.device_count() > 0 else 1.0, True, random.randint(0, max_64_bit_int), 5, 1.003, "Wavelet", "fp32", "fp32", 1.0, True, False, default_setting.spt_linear_CFG_Quality if torch.cuda.device_count() > 0 else 1.0, 0., "v0-Q", "input", 6 ] def check(input_image): if input_image is None: raise gr.Error("请提供要处理的图像。") @spaces.GPU(duration=420) def stage1_process( input_image, gamma_correction, diff_dtype, ae_dtype ): print('stage1_process ==>>') # if torch.cuda.device_count() == 0: # gr.Warning('将此 Spaces 设置为 GPU 配置以使其正常工作。') # return None, None torch.cuda.set_device(BOOXEL_device) LQ = HWC3(np.array(Image.open(input_image))) LQ = fix_resize(LQ, 512) # stage1 LQ = np.array(LQ) / 255 * 2 - 1 LQ = torch.tensor(LQ, dtype=torch.float32).permute(2, 0, 1).unsqueeze(0).to(BOOXEL_device)[:, :3, :, :] model.ae_dtype = convert_dtype(ae_dtype) model.model.dtype = convert_dtype(diff_dtype) LQ = model.batchify_denoise(LQ, is_stage1=True) LQ = (LQ[0].permute(1, 2, 0) * 127.5 + 127.5).cpu().numpy().round().clip(0, 255).astype(np.uint8) # 伽玛校正 LQ = LQ / 255.0 LQ = np.power(LQ, gamma_correction) LQ *= 255.0 LQ = LQ.round().clip(0, 255).astype(np.uint8) print('<<== stage1_process') return LQ, gr.update(visible = True) def stage2_process(*args, **kwargs): try: return restore_in_Xmin(*args, **kwargs) except Exception as e: print('异常的类型 ' + str(type(e))) if type(e).__name__ == "": print('异常的名称 ' + type(e).__name__) raise e def restore_in_Xmin( noisy_image, rotation, denoise_image, prompt, a_prompt, n_prompt, num_samples, min_size, downscale, upscale, edm_steps, s_stage1, s_stage2, s_cfg, randomize_seed, seed, s_churn, s_noise, color_fix_type, diff_dtype, ae_dtype, gamma_correction, linear_CFG, linear_s_stage2, spt_linear_CFG, spt_linear_s_stage2, model_select, output_format, allocation ): print("noisy_image:\n" + str(noisy_image)) print("denoise_image:\n" + str(denoise_image)) print("rotation: " + str(rotation)) print("prompt: " + str(prompt)) print("a_prompt: " + str(a_prompt)) print("n_prompt: " + str(n_prompt)) print("num_samples: " + str(num_samples)) print("min_size: " + str(min_size)) print("downscale: " + str(downscale)) print("upscale: " + str(upscale)) print("edm_steps: " + str(edm_steps)) print("s_stage1: " + str(s_stage1)) print("s_stage2: " + str(s_stage2)) print("s_cfg: " + str(s_cfg)) print("randomize_seed: " + str(randomize_seed)) print("seed: " + str(seed)) print("s_churn: " + str(s_churn)) print("s_noise: " + str(s_noise)) print("color_fix_type: " + str(color_fix_type)) print("diff_dtype: " + str(diff_dtype)) print("ae_dtype: " + str(ae_dtype)) print("gamma_correction: " + str(gamma_correction)) print("linear_CFG: " + str(linear_CFG)) print("linear_s_stage2: " + str(linear_s_stage2)) print("spt_linear_CFG: " + str(spt_linear_CFG)) print("spt_linear_s_stage2: " + str(spt_linear_s_stage2)) print("model_select: " + str(model_select)) print("GPU time allocation: " + str(allocation) + " min") print("output_format: " + str(output_format)) input_format = re.sub(r"^.*\.([^\.]+)$", r"\1", noisy_image) if input_format not in ['png', 'webp', 'jpg', 'jpeg', 'gif', 'bmp', 'heic']: gr.Warning('错误的图像格式。当前仅支持 *.png, *.webp, *.jpg, *.jpeg, *.gif, *.bmp 或 *.heic。') return None, None, None, None if output_format == "input": if noisy_image is None: output_format = "png" else: output_format = input_format print("最终的 output_format:" + str(output_format)) if prompt is None: prompt = "" if a_prompt is None: a_prompt = "" if n_prompt is None: n_prompt = "" if prompt != "" and a_prompt != "": a_prompt = prompt + ", " + a_prompt else: a_prompt = prompt + a_prompt print("最终提示词:" + str(a_prompt)) denoise_image = np.array(Image.open(noisy_image if denoise_image is None else denoise_image)) if rotation == 90: denoise_image = np.array(list(zip(*denoise_image[::-1]))) elif rotation == 180: denoise_image = np.array(list(zip(*denoise_image[::-1]))) denoise_image = np.array(list(zip(*denoise_image[::-1]))) elif rotation == -90: denoise_image = np.array(list(zip(*denoise_image))[::-1]) if 1 < downscale: input_height, input_width, input_channel = denoise_image.shape denoise_image = np.array(Image.fromarray(denoise_image).resize((input_width // downscale, input_height // downscale), Image.LANCZOS)) denoise_image = HWC3(denoise_image) # if torch.cuda.device_count() == 0: # gr.Warning('将此 Spaces 设置为 GPU 配置以使其正常工作。') # return [noisy_image, denoise_image], gr.update(label="可下载的结果为 *." + output_format + " 格式", format = output_format, value = [denoise_image]), None, gr.update(visible=True) if model_select != model.current_model: print('载入 ' + model_select) if model_select == 'v0-Q': model.load_state_dict(ckpt_Q, strict=False) elif model_select == 'v0-F': model.load_state_dict(ckpt_F, strict=False) model.current_model = model_select model.ae_dtype = convert_dtype(ae_dtype) model.model.dtype = convert_dtype(diff_dtype) # 分配 if allocation == 1: return restore_in_1min( noisy_image, denoise_image, prompt, a_prompt, n_prompt, num_samples, min_size, downscale, upscale, edm_steps, s_stage1, s_stage2, s_cfg, randomize_seed, seed, s_churn, s_noise, color_fix_type, diff_dtype, ae_dtype, gamma_correction, linear_CFG, linear_s_stage2, spt_linear_CFG, spt_linear_s_stage2, model_select, output_format, allocation ) if allocation == 2: return restore_in_2min( noisy_image, denoise_image, prompt, a_prompt, n_prompt, num_samples, min_size, downscale, upscale, edm_steps, s_stage1, s_stage2, s_cfg, randomize_seed, seed, s_churn, s_noise, color_fix_type, diff_dtype, ae_dtype, gamma_correction, linear_CFG, linear_s_stage2, spt_linear_CFG, spt_linear_s_stage2, model_select, output_format, allocation ) if allocation == 3: return restore_in_3min( noisy_image, denoise_image, prompt, a_prompt, n_prompt, num_samples, min_size, downscale, upscale, edm_steps, s_stage1, s_stage2, s_cfg, randomize_seed, seed, s_churn, s_noise, color_fix_type, diff_dtype, ae_dtype, gamma_correction, linear_CFG, linear_s_stage2, spt_linear_CFG, spt_linear_s_stage2, model_select, output_format, allocation ) if allocation == 4: return restore_in_4min( noisy_image, denoise_image, prompt, a_prompt, n_prompt, num_samples, min_size, downscale, upscale, edm_steps, s_stage1, s_stage2, s_cfg, randomize_seed, seed, s_churn, s_noise, color_fix_type, diff_dtype, ae_dtype, gamma_correction, linear_CFG, linear_s_stage2, spt_linear_CFG, spt_linear_s_stage2, model_select, output_format, allocation ) if allocation == 5: return restore_in_5min( noisy_image, denoise_image, prompt, a_prompt, n_prompt, num_samples, min_size, downscale, upscale, edm_steps, s_stage1, s_stage2, s_cfg, randomize_seed, seed, s_churn, s_noise, color_fix_type, diff_dtype, ae_dtype, gamma_correction, linear_CFG, linear_s_stage2, spt_linear_CFG, spt_linear_s_stage2, model_select, output_format, allocation ) if allocation == 7: return restore_in_7min( noisy_image, denoise_image, prompt, a_prompt, n_prompt, num_samples, min_size, downscale, upscale, edm_steps, s_stage1, s_stage2, s_cfg, randomize_seed, seed, s_churn, s_noise, color_fix_type, diff_dtype, ae_dtype, gamma_correction, linear_CFG, linear_s_stage2, spt_linear_CFG, spt_linear_s_stage2, model_select, output_format, allocation ) if allocation == 8: return restore_in_8min( noisy_image, denoise_image, prompt, a_prompt, n_prompt, num_samples, min_size, downscale, upscale, edm_steps, s_stage1, s_stage2, s_cfg, randomize_seed, seed, s_churn, s_noise, color_fix_type, diff_dtype, ae_dtype, gamma_correction, linear_CFG, linear_s_stage2, spt_linear_CFG, spt_linear_s_stage2, model_select, output_format, allocation ) if allocation == 9: return restore_in_9min( noisy_image, denoise_image, prompt, a_prompt, n_prompt, num_samples, min_size, downscale, upscale, edm_steps, s_stage1, s_stage2, s_cfg, randomize_seed, seed, s_churn, s_noise, color_fix_type, diff_dtype, ae_dtype, gamma_correction, linear_CFG, linear_s_stage2, spt_linear_CFG, spt_linear_s_stage2, model_select, output_format, allocation ) if allocation == 10: return restore_in_10min( noisy_image, denoise_image, prompt, a_prompt, n_prompt, num_samples, min_size, downscale, upscale, edm_steps, s_stage1, s_stage2, s_cfg, randomize_seed, seed, s_churn, s_noise, color_fix_type, diff_dtype, ae_dtype, gamma_correction, linear_CFG, linear_s_stage2, spt_linear_CFG, spt_linear_s_stage2, model_select, output_format, allocation ) else: return restore_in_6min( noisy_image, denoise_image, prompt, a_prompt, n_prompt, num_samples, min_size, downscale, upscale, edm_steps, s_stage1, s_stage2, s_cfg, randomize_seed, seed, s_churn, s_noise, color_fix_type, diff_dtype, ae_dtype, gamma_correction, linear_CFG, linear_s_stage2, spt_linear_CFG, spt_linear_s_stage2, model_select, output_format, allocation ) @spaces.GPU(duration=59) def restore_in_1min(*args, **kwargs): return restore_on_gpu(*args, **kwargs) @spaces.GPU(duration=119) def restore_in_2min(*args, **kwargs): return restore_on_gpu(*args, **kwargs) @spaces.GPU(duration=179) def restore_in_3min(*args, **kwargs): return restore_on_gpu(*args, **kwargs) @spaces.GPU(duration=239) def restore_in_4min(*args, **kwargs): return restore_on_gpu(*args, **kwargs) @spaces.GPU(duration=299) def restore_in_5min(*args, **kwargs): return restore_on_gpu(*args, **kwargs) @spaces.GPU(duration=359) def restore_in_6min(*args, **kwargs): return restore_on_gpu(*args, **kwargs) @spaces.GPU(duration=419) def restore_in_7min(*args, **kwargs): return restore_on_gpu(*args, **kwargs) @spaces.GPU(duration=479) def restore_in_8min(*args, **kwargs): return restore_on_gpu(*args, **kwargs) @spaces.GPU(duration=539) def restore_in_9min(*args, **kwargs): return restore_on_gpu(*args, **kwargs) @spaces.GPU(duration=599) def restore_in_10min(*args, **kwargs): return restore_on_gpu(*args, **kwargs) def restore_on_gpu( noisy_image, input_image, prompt, a_prompt, n_prompt, num_samples, min_size, downscale, upscale, edm_steps, s_stage1, s_stage2, s_cfg, randomize_seed, seed, s_churn, s_noise, color_fix_type, diff_dtype, ae_dtype, gamma_correction, linear_CFG, linear_s_stage2, spt_linear_CFG, spt_linear_s_stage2, model_select, output_format, allocation ): start = time.time() print('restore ==>>') torch.cuda.set_device(BOOXEL_device) with torch.no_grad(): input_image = upscale_image(input_image, upscale, unit_resolution=32, min_size=min_size) LQ = np.array(input_image) / 255.0 LQ = np.power(LQ, gamma_correction) LQ *= 255.0 LQ = LQ.round().clip(0, 255).astype(np.uint8) LQ = LQ / 255 * 2 - 1 LQ = torch.tensor(LQ, dtype=torch.float32).permute(2, 0, 1).unsqueeze(0).to(BOOXEL_device)[:, :3, :, :] captions = [''] samples = model.batchify_sample(LQ, captions, num_steps=edm_steps, restoration_scale=s_stage1, s_churn=s_churn, s_noise=s_noise, cfg_scale=s_cfg, control_scale=s_stage2, seed=seed, num_samples=num_samples, p_p=a_prompt, n_p=n_prompt, color_fix_type=color_fix_type, use_linear_CFG=linear_CFG, use_linear_control_scale=linear_s_stage2, cfg_scale_start=spt_linear_CFG, control_scale_start=spt_linear_s_stage2) x_samples = (einops.rearrange(samples, 'b c h w -> b h w c') * 127.5 + 127.5).cpu().numpy().round().clip( 0, 255).astype(np.uint8) results = [x_samples[i] for i in range(num_samples)] torch.cuda.empty_cache() # 所有结果的大小相同 input_height, input_width, input_channel = np.array(input_image).shape result_height, result_width, result_channel = np.array(results[0]).shape print('<<== restore') end = time.time() secondes = int(end - start) minutes = math.floor(secondes / 60) secondes = secondes - (minutes * 60) hours = math.floor(minutes / 60) minutes = minutes - (hours * 60) information = ("如果想获得不同的结果,请重新开始。" if randomize_seed else "") + \ "如果您没有得到想要的图片,请在 « 图片描述 » 中添加更多细节。" + \ "等待 " + str(allocation) + " 分钟以避免 GPU 配额处罚,或也可以使用另一台计算机。" + \ "该图片已在 " + \ ((str(hours) + " 小时 ") if hours != 0 else "") + \ ((str(minutes) + " 分钟 ") if hours != 0 or minutes != 0 else "") + \ str(secondes) + " 秒 内生成。" + \ "新图像的分辨率为 " + str(result_width) + \ " 像素宽, " + str(result_height) + \ " 像素高,最终总分辨率为 " + f'{result_width * result_height:,}' + " 像素。" print(information) try: print("初始分辨率:" + f'{input_width * input_height:,}') print("最终分辨率:" + f'{result_width * result_height:,}') print("edm_steps: " + str(edm_steps)) print("num_samples: " + str(num_samples)) print("缩小规模:" + str(downscale)) print("预计分钟数:" + f'{(((result_width * result_height**(1/1.75)) * input_width * input_height * (edm_steps**(1/2)) * (num_samples**(1/2.5)))**(1/2.5)) / 25000:,}') except Exception as e: print('估算错误') # 滑动块中只能显示一张图像 return [noisy_image] + [results[0]], gr.update(label="可下载的结果为 *." + output_format + " 格式", format = output_format, value = results), gr.update(value = information, visible = True), gr.update(visible=True) def load_and_reset(param_setting): print('load_and_reset ==>>') # if torch.cuda.device_count() == 0: # gr.Warning('将此 Spaces 设置为 GPU 配置以使其正常工作。') # return None, None, None, None, None, None, None, None, None, None, None, None, None, None edm_steps = default_setting.edm_steps s_stage2 = 1.0 s_stage1 = -1.0 s_churn = 5 s_noise = 1.003 # 积极提示词 a_prompt = '电影级,高对比度,高度精细,使用哈苏相机拍摄,超精细照片,逼真的最大细节,32K,调色,超高清,极致的细节,皮肤毛孔细节,超清晰度,完美无变形。' # 消极提示词 n_prompt = '绘画,油画,插图,绘图,艺术,素描,动漫,卡通,CG 风格,3D 渲染,虚幻引擎,模糊,混色,不清晰,怪异纹理,丑陋,肮脏,凌乱,质量最差,质量低,框架,水印,签名,JPEG 伪影,变形,低分辨率,过度平滑' color_fix_type = 'Wavelet' spt_linear_s_stage2 = 0.0 linear_s_stage2 = False linear_CFG = True if param_setting == "Quality": s_cfg = default_setting.s_cfg_Quality spt_linear_CFG = default_setting.spt_linear_CFG_Quality model_select = "v0-Q" elif param_setting == "Fidelity": s_cfg = default_setting.s_cfg_Fidelity spt_linear_CFG = default_setting.spt_linear_CFG_Fidelity model_select = "v0-F" else: raise NotImplementedError gr.Info('参数已重置。') print('<<== load_and_reset') return edm_steps, s_cfg, s_stage2, s_stage1, s_churn, s_noise, a_prompt, n_prompt, color_fix_type, linear_CFG, \ linear_s_stage2, spt_linear_CFG, spt_linear_s_stage2, model_select def log_information(result_gallery): print('log_information') if result_gallery is not None: for i, result in enumerate(result_gallery): print(result[0]) def on_select_result(result_slider, result_gallery, evt: gr.SelectData): print('on_select_result') if result_gallery is not None: for i, result in enumerate(result_gallery): print(result[0]) return [result_slider[0], result_gallery[evt.index][0]] # Gradio 接口 with gr.Blocks() as interface: gr.Markdown(""" # BOOXEL —— Boost Pixel! 提供你的提示词,借助先进的生成实验和模型放大的力量,获取非凡的逼真画面。 我们收集了一个包含 600 万张高分辨率、高质量图像的真实世界采集的数据集用于模型训练,每张图像都关联了清晰且详尽的描述性文本注释。 我们提供了使用文本提示操纵恢复图像的能力,此外,还引入了消极质量提示和恢复指导的采样方法,以进一步提高生成图像的质量和保真度。 """) input_image = gr.Image(label="输入图像(*.png, *.webp, *.jpeg, *.jpg, *.gif, *.bmp, *.heic)", show_label=True, type="filepath", height=600, elem_id="image-input") rotation = gr.Radio([["不旋转", 0], ["⤵ 旋转 +90°", 90], ["↩ 旋转 180°", 180], ["⤴ 旋转 -90°", -90]], label="方向校正", info="在还原图像之前,将应用以下旋转功能;人工智能需要良好的定位才能理解内容", value=0, interactive=True, visible=False) with gr.Group(): prompt = gr.Textbox(label="图像描述", info="帮助人工智能理解图像所代表的内容;尽可能多地描述,尤其是我们在原始图像上看不到的细节;可以用任何语言书写", value="", placeholder="长春,上午,秋天,英短蓝白猫,走在,花丛小径上,真实图像", lines=3) upscale = gr.Radio([["x1", 1], ["x2", 2], ["x3", 3], ["x4", 4], ["x5", 5], ["x6", 6], ["x7", 7], ["x8", 8], ["x9", 9], ["x10", 10]], label="像素放大倍率", info="1 到 10 倍放大倍率", value=2, interactive=True) allocation = gr.Radio([["1 min", 1], ["2 min", 2], ["3 min", 3], ["4 min", 4], ["5 min", 5], ["6 min", 6], ["7 min", 7], ["8 min(不建议)", 8], ["9 min(不建议)", 9], ["10 min(不建议)", 10]], label="GPU 分配时间", info="设置为较低值可中止运行;设置为较高值后,下次运行会受到配额处罚", value=5, interactive=True) with gr.Accordion("预降噪(可选)", open=False): gamma_correction = gr.Slider(label="伽玛校正", info="较低的值图像将会更亮,反之亦然", minimum=0.1, maximum=2.0, value=1.0, step=0.1) denoise_button = gr.Button(value="预降噪") denoise_image = gr.Image(label="降噪图像", show_label=True, type="filepath", sources=[], interactive = False, height=600, elem_id="image-s1") denoise_information = gr.HTML(value="如果存在,去噪图像将被用于修复,而不是输入图像。", visible=False) with gr.Accordion("高级选项", open=False): output_format = gr.Radio([["与输入一致", "input"], ["*.png", "png"], ["*.webp", "webp"], ["*.jpeg", "jpeg"], ["*.gif", "gif"], ["*.bmp", "bmp"]], label="生成的图像格式", info="文件扩展名", value="input", interactive=True) a_prompt = gr.Textbox(label="补充图片说明", info="完整的主图像描述", value='电影级,高对比度,高度精细,使用哈苏相机拍摄,超精细照片,逼真的最大细节,32K,调色,超高清,极致的细节,皮肤毛孔细节,超清晰度,完美无变形。', lines=3) n_prompt = gr.Textbox(label="负面图像描述", info="通过列出图像不代表的内容来消除歧义", value='绘画,油画,插图,绘图,艺术,素描,动漫,卡通,CG 风格,3D 渲染,虚幻引擎,模糊,混色,不清晰,怪异纹理,丑陋,肮脏,凌乱,质量最差,质量低,框架,水印,签名,JPEG 伪影,变形,低分辨率,过度平滑', lines=3) edm_steps = gr.Slider(label="步骤数", info="较低的值生成将会更快;较高的值将会获得更多的细节", minimum=1, maximum=200, value=default_setting.edm_steps if torch.cuda.device_count() > 0 else 1, step=1) num_samples = gr.Slider(label="生成数", info="生成的结果图像的数量", minimum=1, maximum=4 if not args.use_image_slider else 1 , value=1, step=1) min_size = gr.Slider(label="最小尺寸", info="结果的最小高度和最小宽度", minimum=32, maximum=4096, value=1024, step=32) downscale = gr.Radio([["/1", 1], ["/2", 2], ["/3", 3], ["/4", 4], ["/5", 5], ["/6", 6], ["/7", 7], ["/8", 8], ["/9", 9], ["/10", 10]], label="缩减前因数", info="减少图像模糊,缩短处理时间", value=1, interactive=True) with gr.Row(): with gr.Column(): model_select = gr.Radio([["质量 (v0-Q)", "v0-Q"], ["保真度 (v0-F)", "v0-F"]], label="模型选择", info="预训练模型", value="v0-Q", interactive=True) with gr.Column(): color_fix_type = gr.Radio([["None", "None"], ["AdaIn (改进风格)", "AdaIn"], ["Wavelet (针对 JPEG 伪图象)", "Wavelet"]], label="色彩修复类型", info="AdaIn 改进画面风格;Wavelet 用于 JPEG 伪图像", value="Wavelet", interactive=True) s_cfg = gr.Slider(label="文本指导等级", info="较低的值将更加跟随源图像;较高的值将更加跟随提示", minimum=1.0, maximum=15.0, value=default_setting.s_cfg_Quality if torch.cuda.device_count() > 0 else 1.0, step=0.1) s_stage2 = gr.Slider(label="修复指导强度", minimum=0., maximum=1., value=1., step=0.05) s_stage1 = gr.Slider(label="预降噪指导强度", minimum=-1.0, maximum=6.0, value=-1.0, step=1.0) s_churn = gr.Slider(label="S-Churn", minimum=0, maximum=40, value=5, step=1) s_noise = gr.Slider(label="S-Noise", minimum=1.0, maximum=1.1, value=1.003, step=0.001) with gr.Row(): with gr.Column(): linear_CFG = gr.Checkbox(label="线性 CFG", value=True) spt_linear_CFG = gr.Slider(label="CFG 起始", minimum=1.0, maximum=9.0, value=default_setting.spt_linear_CFG_Quality if torch.cuda.device_count() > 0 else 1.0, step=0.5) with gr.Column(): linear_s_stage2 = gr.Checkbox(label="线性修复指导", value=False) spt_linear_s_stage2 = gr.Slider(label="指导起始", minimum=0., maximum=1., value=0., step=0.05) with gr.Column(): diff_dtype = gr.Radio([["fp32 (精确)", "fp32"], ["fp16 (中等)", "fp16"], ["bf16 (快速)", "bf16"]], label="扩散数据类型", value="fp32", interactive=True) with gr.Column(): ae_dtype = gr.Radio([["fp32 (精确)", "fp32"], ["bf16 (快速)", "bf16"]], label="自动编码器数据类型", value="fp32", interactive=True) randomize_seed = gr.Checkbox(label = "\U0001F3B2 随机种子", value=True, info="如果选中,结果将总是不同") seed = gr.Slider(label="种子", minimum=0, maximum=max_64_bit_int, step=1, randomize=True) with gr.Group(): param_setting = gr.Radio(["Quality", "Fidelity"], interactive=True, label="预配", value="Quality") restart_button = gr.Button(value="应用预配") with gr.Column(): diffusion_button = gr.Button(value="开始处理", variant="primary", elem_id="process_button") reset_btn = gr.Button(value="重新初始化页面", variant="stop", elem_id="reset_button", visible=False) restore_information = gr.HTML(value="重启进程,获得另一个结果。", visible=False) result_slider = ImageSlider(label='对比结果', show_label=True, interactive=False, elem_id="slider1", show_download_button=False) result_gallery = gr.Gallery(label='可下载的结果', show_label=True, interactive=False, elem_id="gallery1") gr.Examples( examples = [ [ "./Examples/Example1.png", 0, None, "一群人,快乐地在街上行走,逼真,8K,极其精细", "电影级,高对比度,高度精细,使用哈苏相机拍摄,超精细照片,逼真的最大细节,32K,调色,超高清,极致的细节,皮肤毛孔细节,超清晰度,完美无变形。", "绘画,油画,插图,绘图,艺术,素描,动漫,卡通,CG 风格,3D 渲染,虚幻引擎,模糊,混色,不清晰,怪异纹理,丑陋,肮脏,凌乱,质量最差,质量低,框架,水印,签名,JPEG 伪影,变形,低分辨率,过度平滑", 2, 1024, 1, 8, 200, -1, 1, 7.5, False, 42, 5, 1.003, "AdaIn", "fp16", "bf16", 1.0, True, 4, False, 0., "v0-Q", "input", 5 ], [ "./Examples/Example2.jpeg", 0, None, "一只虎斑猫的头部,在一间房子里,逼真,8K,极其细腻。", "电影级,高对比度,高度精细,使用哈苏相机拍摄,超精细照片,逼真的最大细节,32K,调色,超高清,极致的细节,皮肤毛孔细节,超清晰度,完美无变形。", "绘画,油画,插图,绘图,艺术,素描,动漫,卡通,CG 风格,3D 渲染,虚幻引擎,模糊,混色,不清晰,怪异纹理,丑陋,肮脏,凌乱,质量最差,质量低,框架,水印,签名,JPEG 伪影,变形,低分辨率,过度平滑", 1, 1024, 1, 1, 200, -1, 1, 7.5, False, 42, 5, 1.003, "Wavelet", "fp16", "bf16", 1.0, True, 4, False, 0., "v0-Q", "input", 4 ], [ "./Examples/Example3.webp", 0, None, "一个红色的苹果", "电影级,高对比度,高度精细,使用哈苏相机拍摄,超精细照片,逼真的最大细节,32K,调色,超高清,极致的细节,皮肤毛孔细节,超清晰度,完美无变形。", "绘画,油画,插图,绘图,艺术,素描,动漫,卡通,CG 风格,3D 渲染,虚幻引擎,模糊,混色,不清晰,怪异纹理,丑陋,肮脏,凌乱,质量最差,质量低,框架,水印,签名,JPEG 伪影,变形,低分辨率,过度平滑", 1, 1024, 1, 1, 200, -1, 1, 7.5, False, 42, 5, 1.003, "Wavelet", "fp16", "bf16", 1.0, True, 4, False, 0., "v0-Q", "input", 4 ], [ "./Examples/Example3.webp", 0, None, "一块红色大理石", "电影级,高对比度,高度精细,使用哈苏相机拍摄,超精细照片,逼真的最大细节,32K,调色,超高清,极致的细节,皮肤毛孔细节,超清晰度,完美无变形。", "绘画,油画,插图,绘图,艺术,素描,动漫,卡通,CG 风格,3D 渲染,虚幻引擎,模糊,混色,不清晰,怪异纹理,丑陋,肮脏,凌乱,质量最差,质量低,框架,水印,签名,JPEG 伪影,变形,低分辨率,过度平滑", 1, 1024, 1, 1, 200, -1, 1, 7.5, False, 42, 5, 1.003, "Wavelet", "fp16", "bf16", 1.0, True, 4, False, 0., "v0-Q", "input", 4 ], ], run_on_click = True, fn = stage2_process, inputs = [ input_image, rotation, denoise_image, prompt, a_prompt, n_prompt, num_samples, min_size, downscale, upscale, edm_steps, s_stage1, s_stage2, s_cfg, randomize_seed, seed, s_churn, s_noise, color_fix_type, diff_dtype, ae_dtype, gamma_correction, linear_CFG, linear_s_stage2, spt_linear_CFG, spt_linear_s_stage2, model_select, output_format, allocation ], outputs = [ result_slider, result_gallery, restore_information, reset_btn ], cache_examples = False, ) input_image.upload(fn = check_upload, inputs = [ input_image ], outputs = [ rotation ], queue = False, show_progress = False) denoise_button.click(fn = check, inputs = [ input_image ], outputs = [], queue = False, show_progress = False).success(fn = stage1_process, inputs = [ input_image, gamma_correction, diff_dtype, ae_dtype ], outputs=[ denoise_image, denoise_information ]) diffusion_button.click(fn = update_seed, inputs = [ randomize_seed, seed ], outputs = [ seed ], queue = False, show_progress = False).then(fn = check, inputs = [ input_image ], outputs = [], queue = False, show_progress = False).success(fn=stage2_process, inputs = [ input_image, rotation, denoise_image, prompt, a_prompt, n_prompt, num_samples, min_size, downscale, upscale, edm_steps, s_stage1, s_stage2, s_cfg, randomize_seed, seed, s_churn, s_noise, color_fix_type, diff_dtype, ae_dtype, gamma_correction, linear_CFG, linear_s_stage2, spt_linear_CFG, spt_linear_s_stage2, model_select, output_format, allocation ], outputs = [ result_slider, result_gallery, restore_information, reset_btn ]).success(fn = log_information, inputs = [ result_gallery ], outputs = [], queue = False, show_progress = False) result_gallery.change(on_select_result, [result_slider, result_gallery], result_slider) result_gallery.select(on_select_result, [result_slider, result_gallery], result_slider) restart_button.click(fn = load_and_reset, inputs = [ param_setting ], outputs = [ edm_steps, s_cfg, s_stage2, s_stage1, s_churn, s_noise, a_prompt, n_prompt, color_fix_type, linear_CFG, linear_s_stage2, spt_linear_CFG, spt_linear_s_stage2, model_select ]) reset_btn.click(fn = reset, inputs = [], outputs = [ input_image, rotation, denoise_image, prompt, a_prompt, n_prompt, num_samples, min_size, downscale, upscale, edm_steps, s_stage1, s_stage2, s_cfg, randomize_seed, seed, s_churn, s_noise, color_fix_type, diff_dtype, ae_dtype, gamma_correction, linear_CFG, linear_s_stage2, spt_linear_CFG, spt_linear_s_stage2, model_select, output_format, allocation ], queue = False, show_progress = False) interface.queue(10).launch()