Files changed (1) hide show
  1. app.py +56 -142
app.py CHANGED
@@ -1,149 +1,63 @@
 
1
  import gradio as gr
2
- import torch
3
- from diffusers import StableDiffusionPipeline
4
- import gc
5
- from PIL import Image, ImageDraw, ImageFont
6
- import os
7
 
8
- class ImageGenerator:
9
- def __init__(self):
10
- self.device = "cuda" if torch.cuda.is_available() else "cpu"
11
- self.pipe = None
12
-
13
- def load_model(self):
14
- if self.pipe is None:
15
- # 使用較小的模型
16
- model_id = "runwayml/stable-diffusion-v1-5"
17
-
18
- self.pipe = StableDiffusionPipeline.from_pretrained(
19
- model_id,
20
- torch_dtype=torch.float16 if self.device == "cuda" else torch.float32,
21
- safety_checker=None,
22
- requires_safety_checker=False
23
- )
24
-
25
- if self.device == "cuda":
26
- self.pipe = self.pipe.to(self.device)
27
- self.pipe.enable_attention_slicing(1)
28
- self.pipe.enable_model_cpu_offload()
29
-
30
- def unload_model(self):
31
- if self.pipe is not None:
32
- del self.pipe
33
- self.pipe = None
34
- if torch.cuda.is_available():
35
- torch.cuda.empty_cache()
36
- gc.collect()
37
-
38
- def generate(self, prompt: str) -> Image.Image:
39
- try:
40
- self.load_model()
41
-
42
- image = self.pipe(
43
- prompt,
44
- num_inference_steps=20,
45
- guidance_scale=7.5,
46
- height=384, # 降低解析度以節省記憶體
47
- width=384
48
- ).images[0]
49
-
50
- self.unload_model() # 釋放記憶體
51
- return image
52
-
53
- except Exception as e:
54
- error_msg = str(e)
55
- print(f"Error: {error_msg}")
56
- # 創建錯誤提示圖片
57
- error_image = Image.new('RGB', (384, 384), color='white')
58
- draw = ImageDraw.Draw(error_image)
59
- draw.text((10, 10), f"Error: {error_msg}", fill='black')
60
- return error_image
61
 
62
- # 全局變數
63
- generator = ImageGenerator()
64
 
65
- def process_prompt(text: str, language: str) -> str:
66
- """處理提示詞"""
67
- if not text.strip():
68
- return "error: empty prompt"
69
-
70
- if language == "中文":
71
- # 添加英文關鍵詞來增強效果
72
- enhancers = [
73
- "highly detailed",
74
- "8k",
75
- "high quality",
76
- "masterpiece"
77
- ]
78
- return f"{text}, {', '.join(enhancers)}"
79
- return text
80
 
81
- def generate_image(prompt: str, language: str) -> Image.Image:
82
- """處理圖像生成"""
83
- if not prompt.strip():
84
- error_image = Image.new('RGB', (384, 384), color='white')
85
- draw = ImageDraw.Draw(error_image)
86
- draw.text((10, 10), "請輸入提示詞", fill='black')
87
- return error_image
88
-
89
- processed_prompt = process_prompt(prompt, language)
90
- return generator.generate(processed_prompt)
91
 
92
- # 創建 Gradio 介面
93
- with gr.Blocks() as demo:
94
- gr.Markdown("""
95
- ## 🎨 AI 圖像生成系統
96
-
97
- 請在下方輸入您想要生成的圖像描述。
98
-
99
- 注意事項:
100
- 1. 生成過程可能需要 30-60 秒
101
- 2. 如果出現錯誤,請稍等片刻後重試
102
- 3. 中文輸入會自動添加優化關鍵詞
103
- """)
104
-
105
- with gr.Row():
106
- with gr.Column():
107
- prompt = gr.Textbox(
108
- label="創作提示",
109
- placeholder="請輸入描述...",
110
- lines=3
111
- )
112
- language = gr.Radio(
113
- choices=["中文", "English"],
114
- value="中文",
115
- label="語言"
116
- )
117
- generate_btn = gr.Button("🎨 生成圖像", variant="primary")
118
-
119
- with gr.Column():
120
- output_image = gr.Image(label="生成結果")
121
-
122
- # 添加示例
123
- gr.Examples(
124
- examples=[
125
- ["日落時分的古老城堡", "中文"],
126
- ["peaceful mountain lake", "English"],
127
- ["傳統中國水墨畫風格的竹林", "中文"],
128
- ],
129
- inputs=[prompt, language],
130
- outputs=output_image,
131
- fn=generate_image,
132
- cache_examples=True
133
- )
134
-
135
- # 設置點擊事件
136
- generate_btn.click(
137
- fn=generate_image,
138
- inputs=[prompt, language],
139
- outputs=output_image
140
- )
141
 
142
- # 啟動設定
143
- if __name__ == "__main__":
144
- demo.queue(max_size=1) # 限制隊列大小
145
- demo.launch(
146
- show_error=True,
147
- share=True,
148
- server_name="0.0.0.0"
149
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import io, os, base64, random, json, tempfile, ipfshttpclient, torch
2
  import gradio as gr
3
+ from diffusers import StableDiffusionPipeline, ControlNetModel
4
+ from transformers import pipeline
 
 
 
5
 
6
+ # ---- 1. 載入四種模型 ----
7
+ sd_pipe = StableDiffusionPipeline.from_pretrained(
8
+ "stabilityai/stable-diffusion-2-1", torch_dtype=torch.float16
9
+ ).to("cuda")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
+ biggan = pipeline("text-to-image", model="osanseviero/BigGAN-deep-128")
 
12
 
13
+ dalle = pipeline("text-to-image", model="dalle-mini/dalle-mini")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
+ # Hybrid: SD + ControlNet (邊緣控制範例)
16
+ control = ControlNetModel.from_pretrained(
17
+ "lllyasviel/control_v11p_sd15_canny", torch_dtype=torch.float16
18
+ ).to("cuda")
 
 
 
 
 
 
19
 
20
+ def hybrid(prompt):
21
+ # 先跑一次 SD 取得基底
22
+ image = sd_pipe(prompt, num_inference_steps=25).images[0]
23
+ # 取 Canny 邊緣作為條件再跑一次
24
+ import cv2, numpy as np
25
+ edges = cv2.Canny(np.array(image), 100, 200)
26
+ edge_img = cv2.cvtColor(edges, cv2.COLOR_GRAY2RGB)
27
+ final = sd_pipe(prompt, image=edge_img, controlnet=control,
28
+ num_inference_steps=20).images[0]
29
+ return final
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
+ model_dict = {
32
+ "Diffusion (Stable‑Diffusion‑2‑1)": lambda p: sd_pipe(p, num_inference_steps=30).images[0],
33
+ "GAN (BigGAN‑128)": lambda p: biggan(p, guidance_scale=5.0)[0]["image"],
34
+ "Autoregressive (DALL·E Mini)": lambda p: dalle(p, guidance_scale=5.0)[0]["image"],
35
+ "Hybrid (SD + ControlNet)": hybrid,
36
+ }
37
+
38
+ # ---- 2. IPFS 上傳 ----
39
+ client = ipfshttpclient.connect("/dns/localhost/tcp/5001/http") # 或改用 Infura/Pinata
40
+
41
+ def upload_ipfs(pil_img):
42
+ buf = io.BytesIO()
43
+ pil_img.save(buf, format="PNG")
44
+ buf.seek(0)
45
+ res = client.add(buf)
46
+ return f"https://ipfs.io/ipfs/{res['Hash']}"
47
+
48
+ # ---- 3. Gradio 介面 ----
49
+ def generate(prompt, model_name):
50
+ img = model_dict[model_name](prompt)
51
+ cid_url = upload_ipfs(img)
52
+ return img, cid_url
53
+
54
+ with gr.Blocks(title="AI Model Mixer") as demo:
55
+ gr.Markdown("# 🖼️ AI Model Mixer – 4 Models + IPFS")
56
+ prompt = gr.Textbox(label="輸入提示詞")
57
+ model = gr.Dropdown(list(model_dict.keys()), value=list(model_dict.keys())[0], label="選擇模型")
58
+ btn = gr.Button("生成並上傳")
59
+ gallery = gr.Image(label="輸出影像")
60
+ cid_out = gr.Textbox(label="IPFS URL")
61
+ btn.click(generate, inputs=[prompt, model], outputs=[gallery, cid_out])
62
+
63
+ demo.launch()