Akimitsujiro commited on
Commit
a9ae318
·
verified ·
1 Parent(s): 6e5f01a

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +208 -0
  2. requirements.txt +10 -0
app.py ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import spaces
2
+ import gradio as gr
3
+ import numpy as np
4
+ import PIL.Image
5
+ from PIL import Image
6
+ import random
7
+ from diffusers import ControlNetModel, StableDiffusionXLPipeline, AutoencoderKL
8
+ import cv2
9
+ import torch
10
+ import os
11
+ import time
12
+ import glob
13
+
14
+ from diffusers import (
15
+ DDIMScheduler,
16
+ DPMSolverMultistepScheduler,
17
+ EulerDiscreteScheduler,
18
+ EulerAncestralDiscreteScheduler,
19
+ HeunDiscreteScheduler,
20
+ KDPM2DiscreteScheduler,
21
+ KDPM2AncestralDiscreteScheduler,
22
+ LMSDiscreteScheduler,
23
+ UniPCMultistepScheduler,
24
+ )
25
+
26
+ # 一時ファイルの管理設定
27
+ TEMP_DIR = "temp_images"
28
+ FILE_RETENTION_PERIOD = 3600 # 1時間
29
+ os.makedirs(TEMP_DIR, exist_ok=True)
30
+
31
+ def cleanup_old_files():
32
+ """古い一時ファイルを削除する"""
33
+ current_time = time.time()
34
+ pattern = os.path.join(TEMP_DIR, "output_*.png")
35
+
36
+ for file_path in glob.glob(pattern):
37
+ try:
38
+ file_modified_time = os.path.getmtime(file_path)
39
+ if current_time - file_modified_time > FILE_RETENTION_PERIOD:
40
+ os.remove(file_path)
41
+ except Exception as e:
42
+ print(f"Error while cleaning up file {file_path}: {e}")
43
+
44
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
45
+
46
+ pipe = StableDiffusionXLPipeline.from_single_file(
47
+ "https://huggingface.co/bluepen5805/illustrious_pencil-XL/illustrious_pencil-XL-v2.0.0.safetensors",
48
+ use_safetensors=True,
49
+ torch_dtype=torch.float16,
50
+ )
51
+ pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)
52
+ pipe.to(device)
53
+
54
+ MAX_SEED = np.iinfo(np.int32).max
55
+ MAX_IMAGE_SIZE = 1216
56
+
57
+ @spaces.GPU
58
+ def infer(prompt, negative_prompt, seed, randomize_seed, width, height, guidance_scale, num_inference_steps, sampler_name):
59
+ # 古い一時ファイルの削除
60
+ cleanup_old_files()
61
+
62
+ # サンプラーの設定
63
+ if sampler_name == "DDIM":
64
+ pipe.scheduler = DDIMScheduler.from_config(pipe.scheduler.config)
65
+ elif sampler_name == "DPMSolverMultistep":
66
+ pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config)
67
+ elif sampler_name == "Euler":
68
+ pipe.scheduler = EulerDiscreteScheduler.from_config(pipe.scheduler.config)
69
+ elif sampler_name == "EulerAncestral":
70
+ pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)
71
+ elif sampler_name == "Heun":
72
+ pipe.scheduler = HeunDiscreteScheduler.from_config(pipe.scheduler.config)
73
+ elif sampler_name == "KDPM2":
74
+ pipe.scheduler = KDPM2DiscreteScheduler.from_config(pipe.scheduler.config)
75
+ elif sampler_name == "KDPM2Ancestral":
76
+ pipe.scheduler = KDPM2AncestralDiscreteScheduler.from_config(pipe.scheduler.config)
77
+ elif sampler_name == "LMS":
78
+ pipe.scheduler = LMSDiscreteScheduler.from_config(pipe.scheduler.config)
79
+ elif sampler_name == "UniPC":
80
+ pipe.scheduler = UniPCMultistepScheduler.from_config(pipe.scheduler.config)
81
+ else:
82
+ pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)
83
+
84
+ if randomize_seed:
85
+ seed = random.randint(0, MAX_SEED)
86
+
87
+ generator = torch.Generator().manual_seed(seed)
88
+
89
+ output_image = pipe(
90
+ prompt=prompt,
91
+ negative_prompt=negative_prompt,
92
+ guidance_scale=guidance_scale,
93
+ num_inference_steps=num_inference_steps,
94
+ width=width,
95
+ height=height,
96
+ generator=generator
97
+ ).images[0]
98
+
99
+ # RGBモードで保存
100
+ if output_image.mode != 'RGB':
101
+ output_image = output_image.convert('RGB')
102
+
103
+ # 一時ファイルとして保存
104
+ timestamp = int(time.time())
105
+ temp_filename = os.path.join(TEMP_DIR, f"output_{timestamp}.png")
106
+ output_image.save(temp_filename)
107
+
108
+ return temp_filename
109
+
110
+ css = """
111
+ #col-container {
112
+ margin: 0 auto;
113
+ max-width: 520px;
114
+ }
115
+ """
116
+
117
+ with gr.Blocks(css=css) as demo:
118
+ with gr.Column(elem_id="col-container"):
119
+ gr.Markdown("""
120
+ Text-to-Image Demo
121
+ using [illustrious_pencil-XL](https://huggingface.co/bluepen5805/illustrious_pencil-XL)
122
+ """)
123
+
124
+ with gr.Row():
125
+ prompt = gr.Text(
126
+ label="Prompt",
127
+ show_label=False,
128
+ max_lines=1,
129
+ placeholder="Enter your prompt",
130
+ container=False,
131
+ )
132
+ run_button = gr.Button("Run", scale=0)
133
+
134
+ result = gr.Image(
135
+ label="Result",
136
+ show_label=False,
137
+ type="filepath", # filepathに変更
138
+ elem_id="output_image"
139
+ )
140
+
141
+ with gr.Accordion("Advanced Settings", open=False):
142
+ negative_prompt = gr.Text(
143
+ label="Negative prompt",
144
+ max_lines=1,
145
+ placeholder="Enter a negative prompt",
146
+ value="nsfw, (low quality, worst quality:1.2), very displeasing, 3d, watermark, signature, ugly, poorly drawn"
147
+ )
148
+
149
+ seed = gr.Slider(
150
+ label="Seed",
151
+ minimum=0,
152
+ maximum=MAX_SEED,
153
+ step=1,
154
+ value=0,
155
+ )
156
+
157
+ sampler_name = gr.Dropdown(
158
+ label="Sampler",
159
+ choices=["DDIM", "DPMSolverMultistep", "Euler", "EulerAncestral", "Heun", "KDPM2", "KDPM2Ancestral", "LMS", "UniPC"],
160
+ value="EulerAncestral",
161
+ )
162
+
163
+ randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
164
+
165
+ with gr.Row():
166
+ width = gr.Slider(
167
+ label="Width",
168
+ minimum=256,
169
+ maximum=MAX_IMAGE_SIZE,
170
+ step=32,
171
+ value=1024,
172
+ )
173
+
174
+ height = gr.Slider(
175
+ label="Height",
176
+ minimum=256,
177
+ maximum=MAX_IMAGE_SIZE,
178
+ step=32,
179
+ value=1024,
180
+ )
181
+
182
+ with gr.Row():
183
+ guidance_scale = gr.Slider(
184
+ label="Guidance scale",
185
+ minimum=0.0,
186
+ maximum=20.0,
187
+ step=0.1,
188
+ value=4,
189
+ )
190
+
191
+ num_inference_steps = gr.Slider(
192
+ label="Number of inference steps",
193
+ minimum=1,
194
+ maximum=28,
195
+ step=1,
196
+ value=28,
197
+ )
198
+
199
+ run_button.click(
200
+ fn=infer,
201
+ inputs=[prompt, negative_prompt, seed, randomize_seed, width, height, guidance_scale, num_inference_steps, sampler_name],
202
+ outputs=[result]
203
+ )
204
+
205
+ # 起動時に古いファイルを削除
206
+ cleanup_old_files()
207
+
208
+ demo.queue().launch()
requirements.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ accelerate
2
+ diffusers
3
+ Pillow
4
+ safetensors
5
+ torch
6
+ torchvision
7
+ transformers
8
+ xformers
9
+ controlnet-aux==0.0.7
10
+ gradio_imageslider==0.0.20