cocoat commited on
Commit
f0ea9c7
·
verified ·
1 Parent(s): eafdc3d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +21 -160
app.py CHANGED
@@ -1,172 +1,33 @@
1
  import gradio as gr
2
- import torch
3
- import random
4
- import numpy as np
5
- from diffusers import (
6
- StableDiffusionXLPipeline,
7
- EulerAncestralDiscreteScheduler,
8
- DPMSolverMultistepScheduler
9
- )
10
- from huggingface_hub import hf_hub_download
11
 
12
- # デバイスと型の設定
13
- device = "cuda" if torch.cuda.is_available() else "cpu"
14
- torch_dtype = torch.float16 if torch.cuda.is_available() else torch.float32
15
- MAX_SEED = np.iinfo(np.int32).max
16
- MAX_SIZE = 2048
17
 
18
- # モデルファイルのダウンロード
19
- model_path = hf_hub_download(
20
- repo_id="cocoat/cocoamix",
21
- filename="recocoamixXL3_coamixXL3.safetensors"
22
- )
23
-
24
- # 単一ファイルからパイプラインを構築
25
- pipe = StableDiffusionXLPipeline.from_single_file(
26
- model_path,
27
- torch_dtype=torch_dtype,
28
- use_safetensors=True
29
- ).to(device)
30
-
31
- # スケジューラのプリセット
32
- euler_scheduler = EulerAncestralDiscreteScheduler.from_config(
33
- pipe.scheduler.config,
34
- use_karras_sigmas=True
35
- )
36
- dpm_scheduler = DPMSolverMultistepScheduler.from_config(
37
- pipe.scheduler.config
38
- )
39
- pipe.scheduler = euler_scheduler
40
-
41
- # 生成履歴保持
42
- dhistory = []
43
-
44
- # HTMLテーブル生成ヘルパー
45
- def make_html_table(caption):
46
- rows = caption.split("\n")
47
- html = '<table style="width:100%;border-collapse:collapse;">'
48
- for row in rows:
49
- if ": " in row:
50
- key, val = row.split(": ", 1)
51
- html += (
52
- f'<tr><th style="text-align:left;border:1px solid #ddd;padding:4px;">{key}</th>'
53
- f'<td style="border:1px solid #ddd;padding:4px;">{val}</td></tr>'
54
- )
55
- html += '</table>'
56
- return html
57
-
58
- # 推論関数
59
- def infer(
60
- prompt, neg, seed, rand, w, h, cfg, steps, scheduler_type,
61
- progress=gr.Progress(track_tqdm=True)
62
- ):
63
- if rand:
64
- seed = random.randint(0, MAX_SEED)
65
- generator = torch.Generator(device=device).manual_seed(seed)
66
- pipe.scheduler = (
67
- euler_scheduler if scheduler_type == "Euler Ancestral" else dpm_scheduler
68
- )
69
- pipe.scheduler.set_timesteps(steps)
70
- def _callback(pipeline, step_idx, timestep, callback_kwargs):
71
- progress(step_idx/steps, desc=f"Step {step_idx}/{steps}")
72
- return callback_kwargs
73
- output = pipe(
74
- prompt=prompt,
75
- negative_prompt=neg or None,
76
- guidance_scale=cfg,
77
- num_inference_steps=steps,
78
- width=w,
79
- height=h,
80
- generator=generator,
81
- callback_on_step_end=_callback
82
- )
83
- img = output.images[0]
84
- caption_text = (
85
- f"Prompt: {prompt}\n"
86
- f"Negative: {neg or 'None'}\n"
87
- f"Seed: {seed}\n"
88
- f"Size: {w}×{h}\n"
89
- f"CFG: {cfg}\n"
90
- f"Steps: {steps}\n"
91
- f"Scheduler: {scheduler_type}"
92
- )
93
- history.insert(0, (img, caption_text))
94
- progress(1.0, desc="Done!")
95
- gallery_items = [(item[0], make_html_table(item[1])) for item in history]
96
- return img, gallery_items
97
-
98
- # Gradio UI
99
- def main():
100
- with gr.Blocks() as demo:
101
- # カスタム CSS/JS を直接挿入
102
- gr.HTML(_js=None,_html="""
103
  <style>
104
- .loading-screen, .gradio-container > .loading, .gradio-container .loading { display: none !important; }
105
- #custom-loader { display: none; align-items: center; justify-content: center; font-weight: bold; margin: 12px 0; }
106
- body.gradio-running #custom-loader { display: flex !important; }
107
- @keyframes fadeLetter { 0%,100% { opacity:1; } 50% { opacity:0.2; }}
108
- #modal-overlay { display:none; position:fixed; top:0; left:0; width:100vw; height:100vh; background:rgba(0,0,0,0.6); align-items:center; justify-content:center; z-index:9999; }
109
- #modal-content { background:white; border-radius:12px; padding:16px; max-width:80vw; max-height:80vh; overflow:auto; position:relative; }
110
- #modal-close { position:absolute; top:8px; right:8px; background:#c48f61; border:none; color:white; font-size:18px; width:32px; height:32px; border-radius:50%; cursor:pointer; }
111
- #modal-img { max-width:100%; max-height:60vh; display:block; margin:0 auto; }
112
- #modal-caption { margin-top:12px; }
113
  </style>
114
-
115
- <div id="modal-overlay"><div id="modal-content">
116
- <button id="modal-close">×</button>
117
- <img id="modal-img" src="" alt="expanded"/>
118
- <div id="modal-caption"></div>
119
- </div></div>
120
-
121
  <script>
122
- document.addEventListener('click', e => {
123
- const thumb = e.target.closest('.gr-gallery img');
124
- if(thumb) {
125
- document.getElementById('modal-img').src = thumb.src;
126
- const cap = thumb.closest('figure').querySelector('figcaption')?.innerHTML||'';
127
- document.getElementById('modal-caption').innerHTML = cap;
128
  document.getElementById('modal-overlay').style.display = 'flex';
129
- }
130
- if(e.target.id==='modal-close'||e.target.id==='modal-overlay') {
131
  document.getElementById('modal-overlay').style.display = 'none';
132
- }
133
- });
134
  </script>
135
  """)
136
 
137
- with gr.Column(elem_id="col-container"):
138
- gr.Markdown("## SDXL Base – cocoamixXL3 Demo")
139
- gr.Markdown("[Link: Civitai](https://civitai.com/models/1553716?modelVersionId=1855218)")
140
-
141
- gr.HTML(
142
- '<div id="custom-loader">' + ''.join(
143
- f'<span style="animation:fadeLetter 1s ease-in-out infinite;animation-delay:{i*0.1:.1f}s">{c}</span>'
144
- for i,c in enumerate("in progress")
145
- ) + '<img src="/icon.png" style="width:32px;height:32px;border-radius:50%;margin-left:8px;"/></div>'
146
- )
147
-
148
- with gr.Row():
149
- prompt = gr.Textbox(lines=1, placeholder="Prompt…", value="1girl, cocoart, masterpiece, anime,")
150
- neg = gr.Textbox(lines=1, placeholder="Negative prompt", value="low quality, worst quality, …")
151
- with gr.Row():
152
- seed_sl = gr.Slider(0, MAX_SEED, step=1, value=0, label="Seed")
153
- rand = gr.Checkbox(True, label="Randomize seed")
154
- with gr.Row():
155
- width = gr.Slider(256, MAX_SIZE, step=32, value=512, label="Width")
156
- height = gr.Slider(256, MAX_SIZE, step=32, value=512, label="Height")
157
- with gr.Row():
158
- cfg = gr.Slider(1.0, 30.0, step=0.1, value=7.5, label="CFG Scale")
159
- steps = gr.Slider(1, 50, step=1, value=12, label="Steps")
160
- with gr.Row():
161
- scheduler_type = gr.Radio(choices=["Euler Ancestral","DPM++ 2M SDE"], value="Euler Ancestral", label="Scheduler")
162
- run = gr.Button("Generate")
163
-
164
- img_out = gr.Image()
165
- history_gallery = gr.Gallery(label="生成履歴", columns=4, height=280, show_label=False, interactive=True, type="pil")
166
-
167
- run.click(fn=infer, inputs=[prompt, neg, seed_sl, rand, width, height, cfg, steps, scheduler_type], outputs=[img_out, history_gallery])
168
- demo.queue()
169
- demo.launch()
170
 
171
- if __name__ == "__main__":
172
- main()
 
1
  import gradio as gr
 
 
 
 
 
 
 
 
 
2
 
3
+ def noop(): return None
 
 
 
 
4
 
5
+ with gr.Blocks() as demo:
6
+ # カスタム CSS/JS を最上部にまとめて挿入
7
+ gr.HTML("""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  <style>
9
+ /* モーダルオーバーレイ */
10
+ #modal-overlay { display:none; position:fixed; top:0; left:0; width:100vw; height:100vh;
11
+ background:rgba(0,0,0,0.6); align-items:center; justify-content:center; z-index:9999; }
12
+ #modal-content { background:#fff; padding:20px; border-radius:8px; }
 
 
 
 
 
13
  </style>
14
+ <div id="modal-overlay">
15
+ <div id="modal-content">
16
+ <p>モーダルが開きました!</p>
17
+ <button id="modal-close">閉じる</button>
18
+ </div>
19
+ </div>
 
20
  <script>
21
+ document.getElementById('open-modal').addEventListener('click', () => {
 
 
 
 
 
22
  document.getElementById('modal-overlay').style.display = 'flex';
23
+ });
24
+ document.getElementById('modal-close').addEventListener('click', () => {
25
  document.getElementById('modal-overlay').style.display = 'none';
26
+ });
 
27
  </script>
28
  """)
29
 
30
+ # ② ボタンをひとつ置いてテスト
31
+ btn = gr.Button("モーダルを開く", elem_id="open-modal")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
+ demo.launch()