ginipick commited on
Commit
a0c40c2
ยท
verified ยท
1 Parent(s): 6943716

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +244 -0
app.py ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import replicate
3
+ import requests
4
+ import os
5
+ import json
6
+ from io import BytesIO
7
+ from PIL import Image
8
+
9
+ # ํ™˜๊ฒฝ ๋ณ€์ˆ˜์—์„œ ํ† ํฐ ๊ฐ€์ ธ์˜ค๊ธฐ
10
+ REPLICATE_API_TOKEN = os.getenv("RAPI_TOKEN")
11
+ FRIENDLI_TOKEN = os.getenv("FRIENDLI_TOKEN")
12
+
13
+ def generate_prompt_with_llm(topic):
14
+ """์ฃผ์ œ๋ฅผ ๋ฐ›์•„์„œ LLM์„ ์‚ฌ์šฉํ•ด ์ด๋ฏธ์ง€ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ƒ์„ฑ"""
15
+ url = "https://api.friendli.ai/dedicated/v1/chat/completions"
16
+ headers = {
17
+ "Authorization": f"Bearer {FRIENDLI_TOKEN}",
18
+ "Content-Type": "application/json"
19
+ }
20
+
21
+ # ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ์„ ์œ„ํ•œ ์‹œ์Šคํ…œ ๋ฉ”์‹œ์ง€
22
+ system_prompt = """๋‹น์‹ ์€ ์ด๋ฏธ์ง€ ์ƒ์„ฑ์„ ์œ„ํ•œ ํ”„๋กฌํ”„ํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ์ „๋ฌธ๊ฐ€์ž…๋‹ˆ๋‹ค.
23
+ ์‚ฌ์šฉ์ž๊ฐ€ ์ฃผ์ œ๋ฅผ ์ œ๊ณตํ•˜๋ฉด, ๊ทธ ์ฃผ์ œ์— ๋งž๋Š” ์ƒ์„ธํ•˜๊ณ  ์ฐฝ์˜์ ์ธ ์ด๋ฏธ์ง€ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ƒ์„ฑํ•ด์ฃผ์„ธ์š”.
24
+ ํ”„๋กฌํ”„ํŠธ๋Š” ๊ตฌ์ฒด์ ์ธ ์‹œ๊ฐ์  ์š”์†Œ, ์Šคํƒ€์ผ, ๋ถ„์œ„๊ธฐ, ์ƒ‰์ƒ ๋“ฑ์„ ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
25
+ ์‘๋‹ต์€ ํ”„๋กฌํ”„ํŠธ๋งŒ ๋ฐ˜ํ™˜ํ•˜๊ณ  ๋‹ค๋ฅธ ์„ค๋ช…์€ ํฌํ•จํ•˜์ง€ ๋งˆ์„ธ์š”."""
26
+
27
+ payload = {
28
+ "model": "dep89a2fld32mcm",
29
+ "messages": [
30
+ {
31
+ "role": "system",
32
+ "content": system_prompt
33
+ },
34
+ {
35
+ "role": "user",
36
+ "content": f"๋‹ค์Œ ์ฃผ์ œ์— ๋Œ€ํ•œ ์ด๋ฏธ์ง€ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ƒ์„ฑํ•ด์ฃผ์„ธ์š”: {topic}"
37
+ }
38
+ ],
39
+ "max_tokens": 200,
40
+ "top_p": 0.8,
41
+ "stream": False
42
+ }
43
+
44
+ try:
45
+ response = requests.post(url, json=payload, headers=headers)
46
+ if response.status_code == 200:
47
+ result = response.json()
48
+ return result['choices'][0]['message']['content'].strip()
49
+ else:
50
+ return f"ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ ์‹คํŒจ: {response.status_code}"
51
+ except Exception as e:
52
+ return f"ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}"
53
+
54
+ def translate_to_english(text):
55
+ """ํ•œ๊ธ€ ํ…์ŠคํŠธ๋ฅผ ์˜์–ด๋กœ ๋ฒˆ์—ญ (LLM ์‚ฌ์šฉ)"""
56
+ # ๊ฐ„๋‹จํ•œ ํ•œ๊ธ€ ์ฒดํฌ
57
+ if not any(ord('๊ฐ€') <= ord(char) <= ord('ํžฃ') for char in text):
58
+ return text # ํ•œ๊ธ€์ด ์—†์œผ๋ฉด ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜
59
+
60
+ url = "https://api.friendli.ai/dedicated/v1/chat/completions"
61
+ headers = {
62
+ "Authorization": f"Bearer {FRIENDLI_TOKEN}",
63
+ "Content-Type": "application/json"
64
+ }
65
+
66
+ payload = {
67
+ "model": "dep89a2fld32mcm",
68
+ "messages": [
69
+ {
70
+ "role": "system",
71
+ "content": "You are a translator. Translate the given Korean text to English. Only return the translation without any explanation."
72
+ },
73
+ {
74
+ "role": "user",
75
+ "content": text
76
+ }
77
+ ],
78
+ "max_tokens": 500,
79
+ "top_p": 0.8,
80
+ "stream": False
81
+ }
82
+
83
+ try:
84
+ response = requests.post(url, json=payload, headers=headers)
85
+ if response.status_code == 200:
86
+ result = response.json()
87
+ return result['choices'][0]['message']['content'].strip()
88
+ else:
89
+ return text # ๋ฒˆ์—ญ ์‹คํŒจ์‹œ ์›๋ณธ ๋ฐ˜ํ™˜
90
+ except Exception as e:
91
+ return text # ์˜ค๋ฅ˜ ๋ฐœ์ƒ์‹œ ์›๋ณธ ๋ฐ˜ํ™˜
92
+
93
+ def generate_image(prompt, seed=10):
94
+ """Replicate API๋ฅผ ์‚ฌ์šฉํ•ด ์ด๋ฏธ์ง€ ์ƒ์„ฑ"""
95
+ try:
96
+ # ํ•œ๊ธ€์ด ํฌํ•จ๋œ ๊ฒฝ์šฐ ์˜์–ด๋กœ ๋ฒˆ์—ญ
97
+ english_prompt = translate_to_english(prompt)
98
+
99
+ # Replicate ํด๋ผ์ด์–ธํŠธ ์ดˆ๊ธฐํ™”
100
+ if not REPLICATE_API_TOKEN:
101
+ return None, "RAPI_TOKEN ํ™˜๊ฒฝ๋ณ€์ˆ˜๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค."
102
+
103
+ client = replicate.Client(api_token=REPLICATE_API_TOKEN)
104
+
105
+ # ์ด๋ฏธ์ง€ ์ƒ์„ฑ
106
+ input_params = {
107
+ "seed": seed,
108
+ "prompt": english_prompt,
109
+ "speed_mode": "Extra Juiced ๐Ÿš€ (even more speed)",
110
+ "output_quality": 80
111
+ }
112
+
113
+ output = client.run(
114
+ "prunaai/hidream-l1-fast:17c237d753218fed0ed477cb553902b6b75735f48c128537ab829096ef3d3645",
115
+ input=input_params
116
+ )
117
+
118
+ # ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ ์ฝ๊ธฐ
119
+ if output:
120
+ # output์ด URL์ธ ๊ฒฝ์šฐ
121
+ if isinstance(output, str) and output.startswith('http'):
122
+ response = requests.get(output)
123
+ img = Image.open(BytesIO(response.content))
124
+ return img, f"์‚ฌ์šฉ๋œ ์˜์–ด ํ”„๋กฌํ”„ํŠธ: {english_prompt}"
125
+ # output์ด ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ์ธ ๊ฒฝ์šฐ
126
+ else:
127
+ img = Image.open(BytesIO(output.read()))
128
+ return img, f"์‚ฌ์šฉ๋œ ์˜์–ด ํ”„๋กฌํ”„ํŠธ: {english_prompt}"
129
+ else:
130
+ return None, "์ด๋ฏธ์ง€ ์ƒ์„ฑ ์‹คํŒจ"
131
+
132
+ except Exception as e:
133
+ return None, f"์ด๋ฏธ์ง€ ์ƒ์„ฑ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}"
134
+
135
+ def process_topic_to_image(topic, manual_prompt, use_manual, seed):
136
+ """์ฃผ์ œ๋ฅผ ๋ฐ›์•„์„œ ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ ํ›„ ์ด๋ฏธ์ง€ ์ƒ์„ฑ"""
137
+ if use_manual and manual_prompt.strip():
138
+ # ์ˆ˜๋™ ํ”„๋กฌํ”„ํŠธ ์‚ฌ์šฉ
139
+ prompt = manual_prompt.strip()
140
+ else:
141
+ # LLM์œผ๋กœ ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ
142
+ prompt = generate_prompt_with_llm(topic)
143
+ if "์˜ค๋ฅ˜" in prompt or "์‹คํŒจ" in prompt:
144
+ return None, prompt, prompt
145
+
146
+ # ์ด๋ฏธ์ง€ ์ƒ์„ฑ
147
+ image, status = generate_image(prompt, seed)
148
+
149
+ return image, prompt, status
150
+
151
+ # Gradio ์ธํ„ฐํŽ˜์ด์Šค ์ƒ์„ฑ
152
+ with gr.Blocks(title="AI ์ด๋ฏธ์ง€ ์ƒ์„ฑ๊ธฐ") as demo:
153
+ gr.Markdown("""
154
+ # ๐ŸŽจ AI ์ด๋ฏธ์ง€ ์ƒ์„ฑ๊ธฐ
155
+
156
+ ์ฃผ์ œ๋ฅผ ์ž…๋ ฅํ•˜๋ฉด AI๊ฐ€ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.
157
+ ํ”„๋กฌํ”„ํŠธ๋Š” ์ž๋™ ์ƒ์„ฑ๋˜๊ฑฐ๋‚˜ ์ง์ ‘ ํŽธ์ง‘ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํ•œ๊ธ€ ํ”„๋กฌํ”„ํŠธ๋Š” ์ž๋™์œผ๋กœ ์˜์–ด๋กœ ๋ฒˆ์—ญ๋ฉ๋‹ˆ๋‹ค.
158
+ """)
159
+
160
+ with gr.Row():
161
+ with gr.Column(scale=1):
162
+ topic_input = gr.Textbox(
163
+ label="์ฃผ์ œ ์ž…๋ ฅ",
164
+ placeholder="์˜ˆ: ์šฐ์ฃผ๋ฅผ ์—ฌํ–‰ํ•˜๋Š” ๊ณ ์–‘์ด",
165
+ lines=2
166
+ )
167
+
168
+ generated_prompt = gr.Textbox(
169
+ label="์ƒ์„ฑ๋œ ํ”„๋กฌํ”„ํŠธ (ํŽธ์ง‘ ๊ฐ€๋Šฅ)",
170
+ placeholder="์ž๋™์œผ๋กœ ์ƒ์„ฑ๋œ ํ”„๋กฌํ”„ํŠธ๊ฐ€ ์—ฌ๊ธฐ์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.",
171
+ lines=3
172
+ )
173
+
174
+ use_manual_checkbox = gr.Checkbox(
175
+ label="์ˆ˜๋™ ํ”„๋กฌํ”„ํŠธ ์‚ฌ์šฉ",
176
+ value=False
177
+ )
178
+
179
+ seed_input = gr.Slider(
180
+ minimum=1,
181
+ maximum=100,
182
+ value=10,
183
+ step=1,
184
+ label="์‹œ๋“œ ๊ฐ’ (๋™์ผํ•œ ์‹œ๋“œ๋Š” ๋™์ผํ•œ ์ด๋ฏธ์ง€ ์ƒ์„ฑ)"
185
+ )
186
+
187
+ generate_prompt_btn = gr.Button("ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ", variant="secondary")
188
+ generate_image_btn = gr.Button("์ด๋ฏธ์ง€ ์ƒ์„ฑ", variant="primary")
189
+
190
+ with gr.Column(scale=1):
191
+ output_image = gr.Image(
192
+ label="์ƒ์„ฑ๋œ ์ด๋ฏธ์ง€",
193
+ type="pil"
194
+ )
195
+
196
+ status_text = gr.Textbox(
197
+ label="์ƒํƒœ ๋ฉ”์‹œ์ง€",
198
+ lines=2,
199
+ interactive=False
200
+ )
201
+
202
+ # ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ ๋ฒ„ํŠผ ํด๋ฆญ ์ด๋ฒคํŠธ
203
+ def generate_prompt_only(topic):
204
+ if not topic.strip():
205
+ return "์ฃผ์ œ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”."
206
+ prompt = generate_prompt_with_llm(topic)
207
+ return prompt
208
+
209
+ generate_prompt_btn.click(
210
+ fn=generate_prompt_only,
211
+ inputs=[topic_input],
212
+ outputs=[generated_prompt]
213
+ )
214
+
215
+ # ์ด๋ฏธ์ง€ ์ƒ์„ฑ ๋ฒ„ํŠผ ํด๋ฆญ ์ด๋ฒคํŠธ
216
+ generate_image_btn.click(
217
+ fn=process_topic_to_image,
218
+ inputs=[topic_input, generated_prompt, use_manual_checkbox, seed_input],
219
+ outputs=[output_image, generated_prompt, status_text]
220
+ )
221
+
222
+ gr.Markdown("""
223
+ ---
224
+ ### ์‚ฌ์šฉ ๋ฐฉ๋ฒ•:
225
+ 1. **์ฃผ์ œ ์ž…๋ ฅ**: ์›ํ•˜๋Š” ์ด๋ฏธ์ง€์˜ ์ฃผ์ œ๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”.
226
+ 2. **ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ**: "ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ" ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด AI๊ฐ€ ์ž๋™์œผ๋กœ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
227
+ 3. **ํ”„๋กฌํ”„ํŠธ ํŽธ์ง‘**: ์ƒ์„ฑ๋œ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์›ํ•˜๋Š” ๋Œ€๋กœ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
228
+ 4. **์ด๋ฏธ์ง€ ์ƒ์„ฑ**: "์ด๋ฏธ์ง€ ์ƒ์„ฑ" ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์ด๋ฏธ์ง€๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
229
+
230
+ ๐Ÿ’ก **ํŒ**:
231
+ - ํ•œ๊ธ€ ํ”„๋กฌํ”„ํŠธ๋Š” ์ž๋™์œผ๋กœ ์˜์–ด๋กœ ๋ฒˆ์—ญ๋˜์–ด ์ „์†ก๋ฉ๋‹ˆ๋‹ค.
232
+ - ์‹œ๋“œ ๊ฐ’์„ ๊ณ ์ •ํ•˜๋ฉด ๋™์ผํ•œ ํ”„๋กฌํ”„ํŠธ๋กœ ๋™์ผํ•œ ์ด๋ฏธ์ง€๋ฅผ ์žฌ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
233
+ - "์ˆ˜๋™ ํ”„๋กฌํ”„ํŠธ ์‚ฌ์šฉ"์„ ์ฒดํฌํ•˜๋ฉด ์ฃผ์ œ ๊ธฐ๋ฐ˜ ์ž๋™ ์ƒ์„ฑ์„ ๊ฑด๋„ˆ๋›ฐ๊ณ  ์ง์ ‘ ์ž…๋ ฅํ•œ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
234
+ """)
235
+
236
+ # ์•ฑ ์‹คํ–‰
237
+ if __name__ == "__main__":
238
+ # ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ํ™•์ธ
239
+ if not REPLICATE_API_TOKEN:
240
+ print("๊ฒฝ๊ณ : RAPI_TOKEN ํ™˜๊ฒฝ ๋ณ€์ˆ˜๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.")
241
+ if not FRIENDLI_TOKEN:
242
+ print("๊ฒฝ๊ณ : FRIENDLI_TOKEN ํ™˜๊ฒฝ ๋ณ€์ˆ˜๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.")
243
+
244
+ demo.launch()