Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,32 +1,21 @@
|
|
1 |
import gradio as gr
|
2 |
from transformers import MarianMTModel, MarianTokenizer
|
3 |
|
4 |
-
#
|
5 |
-
# 1) โหลดโมเดลแปลภาษา (MarianMT) จาก Hugging Face
|
6 |
-
# ใช้โมเดล "Helsinki-NLP/opus-mt-th-en"
|
7 |
-
# ==============================
|
8 |
model_name = "Helsinki-NLP/opus-mt-th-en"
|
9 |
tokenizer = MarianTokenizer.from_pretrained(model_name)
|
10 |
model = MarianMTModel.from_pretrained(model_name)
|
11 |
|
12 |
def translate_th_to_en(th_text: str) -> str:
|
13 |
-
"""
|
14 |
-
แปลข้อความภาษาไทยเป็นอังกฤษ ใช้ MarianMTModel แบบ Offline
|
15 |
-
"""
|
16 |
th_text = th_text.strip()
|
17 |
if not th_text:
|
18 |
return ""
|
19 |
-
# สร้าง input token
|
20 |
inputs = tokenizer(th_text, return_tensors="pt", max_length=512, truncation=True)
|
21 |
-
# สร้าง output token (การแปล)
|
22 |
translation_tokens = model.generate(**inputs, max_length=512)
|
23 |
-
# ถอดรหัสเป็น string
|
24 |
en_text = tokenizer.decode(translation_tokens[0], skip_special_tokens=True)
|
25 |
return en_text
|
26 |
|
27 |
-
#
|
28 |
-
# 2) ตัวเลือก (ภาษาไทย) สำหรับมอนสเตอร์
|
29 |
-
# ==============================
|
30 |
body_shapes_th = [
|
31 |
"ตัวเหนียวขยุกขยิก", "ตัวปุกปุยกลม", "ตัวเต็มไปด้วยหนาม",
|
32 |
"ตัวเล็กเหมือนแมลง", "ตัวโปร่งแสงลอยได้"
|
@@ -53,21 +42,36 @@ moods_th = [
|
|
53 |
"ซนเป็นลิง", "ขี้อาย"
|
54 |
]
|
55 |
|
56 |
-
#
|
57 |
-
|
58 |
-
|
59 |
-
|
|
|
|
|
|
|
|
|
|
|
60 |
"""
|
61 |
-
|
|
|
|
|
62 |
"""
|
63 |
-
# (a)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
desc_th = (
|
65 |
f"มอนสเตอร์อารมณ์{mood_th} มี{body_th} "
|
66 |
f"พร้อมด้วย{head_th}, {arms_th}, "
|
67 |
f"ผิว/ลายแบบ{skin_th}, และพลังพิเศษคือ{ability_th}!"
|
68 |
)
|
69 |
|
70 |
-
# (
|
71 |
body_en = translate_th_to_en(body_th)
|
72 |
head_en = translate_th_to_en(head_th)
|
73 |
arms_en = translate_th_to_en(arms_th)
|
@@ -75,8 +79,7 @@ def generate_monster_lab(body_th, head_th, arms_th, skin_th, ability_th, mood_th
|
|
75 |
ability_en = translate_th_to_en(ability_th)
|
76 |
mood_en = translate_th_to_en(mood_th)
|
77 |
|
78 |
-
# (
|
79 |
-
# ex: "This is a [mood_en] monster with [body_en], a [head_en], [arms_en], covered in [skin_en] skin, and it can [ability_en]!"
|
80 |
prompt_en = (
|
81 |
f"This is a {mood_en} monster with {body_en}, "
|
82 |
f"a {head_en}, {arms_en}, covered in {skin_en} skin, "
|
@@ -85,15 +88,12 @@ def generate_monster_lab(body_th, head_th, arms_th, skin_th, ability_th, mood_th
|
|
85 |
|
86 |
return desc_th, prompt_en
|
87 |
|
88 |
-
#
|
89 |
-
# 4) สร้าง UI (Gradio)
|
90 |
-
# ==============================
|
91 |
css_code = """
|
92 |
body {
|
93 |
background-color: #FFF7EA;
|
94 |
font-family: "Kanit", sans-serif;
|
95 |
}
|
96 |
-
|
97 |
#title {
|
98 |
color: #FF6F91;
|
99 |
text-align: center;
|
@@ -118,6 +118,7 @@ body {
|
|
118 |
font-size: 1.1rem;
|
119 |
padding: 10px 20px;
|
120 |
border-radius: 10px;
|
|
|
121 |
}
|
122 |
.monster-btn:hover {
|
123 |
background-color: #FFD54F;
|
@@ -132,48 +133,73 @@ body {
|
|
132 |
"""
|
133 |
|
134 |
def initial_text():
|
135 |
-
""
|
136 |
-
แสดงข้อความเริ่มต้นเมื่อเปิดเว็บครั้งแรก
|
137 |
-
"""
|
138 |
-
return "ยังไม่ได้สร้างมอนสเตอร์นะจ๊ะ เลือกค่าต่าง ๆ แล้วกด 'สร้างมอนสเตอร์!' ดูสิ"
|
139 |
|
140 |
with gr.Blocks(css=css_code) as demo:
|
141 |
-
gr.Markdown("<h1 id='title'>ZenityX Monster Lab (
|
142 |
-
gr.Markdown(
|
143 |
-
|
144 |
-
<
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
171 |
fn=generate_monster_lab,
|
172 |
-
inputs=[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
173 |
outputs=[monster_desc_th, monster_prompt_en]
|
174 |
)
|
175 |
|
176 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
177 |
demo.load(fn=initial_text, inputs=None, outputs=monster_desc_th)
|
178 |
|
179 |
demo.launch()
|
|
|
1 |
import gradio as gr
|
2 |
from transformers import MarianMTModel, MarianTokenizer
|
3 |
|
4 |
+
# ===== 1) โหลดโมเดลแปล (MarianMT) =====
|
|
|
|
|
|
|
5 |
model_name = "Helsinki-NLP/opus-mt-th-en"
|
6 |
tokenizer = MarianTokenizer.from_pretrained(model_name)
|
7 |
model = MarianMTModel.from_pretrained(model_name)
|
8 |
|
9 |
def translate_th_to_en(th_text: str) -> str:
|
|
|
|
|
|
|
10 |
th_text = th_text.strip()
|
11 |
if not th_text:
|
12 |
return ""
|
|
|
13 |
inputs = tokenizer(th_text, return_tensors="pt", max_length=512, truncation=True)
|
|
|
14 |
translation_tokens = model.generate(**inputs, max_length=512)
|
|
|
15 |
en_text = tokenizer.decode(translation_tokens[0], skip_special_tokens=True)
|
16 |
return en_text
|
17 |
|
18 |
+
# ===== 2) ตัวเลือก (ภาษาไทย) สำหรับ Dropdown =====
|
|
|
|
|
19 |
body_shapes_th = [
|
20 |
"ตัวเหนียวขยุกขยิก", "ตัวปุกปุยกลม", "ตัวเต็มไปด้วยหนาม",
|
21 |
"ตัวเล็กเหมือนแมลง", "ตัวโปร่งแสงลอยได้"
|
|
|
42 |
"ซนเป็นลิง", "ขี้อาย"
|
43 |
]
|
44 |
|
45 |
+
# ===== 3) ฟังก์ชันสร้างมอนสเตอร์ =====
|
46 |
+
def generate_monster_lab(
|
47 |
+
body_dd, body_tb,
|
48 |
+
head_dd, head_tb,
|
49 |
+
arms_dd, arms_tb,
|
50 |
+
skin_dd, skin_tb,
|
51 |
+
ability_dd, ability_tb,
|
52 |
+
mood_dd, mood_tb,
|
53 |
+
):
|
54 |
"""
|
55 |
+
ตรวจสอบว่าใน textbox แต่ละหมวดมีข้อความไหม
|
56 |
+
ถ้ามี ให้ใช้ข้อความนั้นแทนค่าใน dropdown
|
57 |
+
ถ้า textbox ว่าง ก็ใช้ค่าจาก dropdown
|
58 |
"""
|
59 |
+
# (a) ตัดสินใจเลือกค่า "ภาษาไทย" แต่ละหมวด
|
60 |
+
body_th = body_tb.strip() if body_tb.strip() else body_dd
|
61 |
+
head_th = head_tb.strip() if head_tb.strip() else head_dd
|
62 |
+
arms_th = arms_tb.strip() if arms_tb.strip() else arms_dd
|
63 |
+
skin_th = skin_tb.strip() if skin_tb.strip() else skin_dd
|
64 |
+
ability_th = ability_tb.strip() if ability_tb.strip() else ability_dd
|
65 |
+
mood_th = mood_tb.strip() if mood_tb.strip() else mood_dd
|
66 |
+
|
67 |
+
# (b) สร้าง “รายละเอียด (ไทย)”
|
68 |
desc_th = (
|
69 |
f"มอนสเตอร์อารมณ์{mood_th} มี{body_th} "
|
70 |
f"พร้อมด้วย{head_th}, {arms_th}, "
|
71 |
f"ผิว/ลายแบบ{skin_th}, และพลังพิเศษคือ{ability_th}!"
|
72 |
)
|
73 |
|
74 |
+
# (c) แปล -> อังกฤษ
|
75 |
body_en = translate_th_to_en(body_th)
|
76 |
head_en = translate_th_to_en(head_th)
|
77 |
arms_en = translate_th_to_en(arms_th)
|
|
|
79 |
ability_en = translate_th_to_en(ability_th)
|
80 |
mood_en = translate_th_to_en(mood_th)
|
81 |
|
82 |
+
# (d) ประกอบ Prompt อังกฤษ
|
|
|
83 |
prompt_en = (
|
84 |
f"This is a {mood_en} monster with {body_en}, "
|
85 |
f"a {head_en}, {arms_en}, covered in {skin_en} skin, "
|
|
|
88 |
|
89 |
return desc_th, prompt_en
|
90 |
|
91 |
+
# ===== 4) สร้าง UI (Gradio) =====
|
|
|
|
|
92 |
css_code = """
|
93 |
body {
|
94 |
background-color: #FFF7EA;
|
95 |
font-family: "Kanit", sans-serif;
|
96 |
}
|
|
|
97 |
#title {
|
98 |
color: #FF6F91;
|
99 |
text-align: center;
|
|
|
118 |
font-size: 1.1rem;
|
119 |
padding: 10px 20px;
|
120 |
border-radius: 10px;
|
121 |
+
margin-right: 10px;
|
122 |
}
|
123 |
.monster-btn:hover {
|
124 |
background-color: #FFD54F;
|
|
|
133 |
"""
|
134 |
|
135 |
def initial_text():
|
136 |
+
return "ยังไม่ได้สร้างมอนสเตอร์นะจ๊ะ ลองเลือก/พิมพ์ แล้วกด 'สร้างมอนสเตอร์!'"
|
|
|
|
|
|
|
137 |
|
138 |
with gr.Blocks(css=css_code) as demo:
|
139 |
+
gr.Markdown("<h1 id='title'>ZenityX Monster Lab (Dropdown + Textbox)</h1>")
|
140 |
+
gr.Markdown("""
|
141 |
+
<div class="game-desc">
|
142 |
+
<p>หนูน้อยจ๊ะ เลือกได้เลยว่าจะใช้ค่าใน <strong>Dropdown</strong> หรือจะ <strong>พิมพ์เอง</strong>
|
143 |
+
(ถ้าพิมพ์เอง ช่อง Dropdown จะถูกข้าม) นะจ๊ะ</p>
|
144 |
+
<p>เมื่อกด <strong>"สร้างมอนสเตอร์!"</strong> แล้วจะได้ <i>รายละเอียด (ไทย)</i> และ <i>Prompt ภาษาอังกฤษ</i> สำหรับ AI</p>
|
145 |
+
<p>อย่าลืมกดปุ่ม <strong>"Copy Prompt"</strong> ถ้าอยากคัดลอกไปใช้ใน AI สร้างภาพด้วยล่ะ!</p>
|
146 |
+
</div>
|
147 |
+
""")
|
148 |
+
|
149 |
+
with gr.Row():
|
150 |
+
with gr.Column():
|
151 |
+
body_dd = gr.Dropdown(body_shapes_th, label="รูปร่าง (Dropdown)", value=body_shapes_th[0])
|
152 |
+
body_tb = gr.Textbox(label="หรือพิมพ์เอง (Body)", placeholder="ตัวโคลนยืดหยุ่น...")
|
153 |
+
|
154 |
+
head_dd = gr.Dropdown(heads_th, label="หัว/ใบหน้า (Dropdown)", value=heads_th[0])
|
155 |
+
head_tb = gr.Textbox(label="หรือพิมพ์เอง (Head)", placeholder="หัวปลาหมึกสุดแปลก...")
|
156 |
+
|
157 |
+
with gr.Column():
|
158 |
+
arms_dd = gr.Dropdown(arms_legs_th, label="แขนขา (Dropdown)", value=arms_legs_th[0])
|
159 |
+
arms_tb = gr.Textbox(label="หรือพิมพ์เอง (Arms/Legs)", placeholder="แขนออกรากไม้...")
|
160 |
+
|
161 |
+
skin_dd = gr.Dropdown(skin_patterns_th, label="ผิว/ลวดลาย (Dropdown)", value=skin_patterns_th[0])
|
162 |
+
skin_tb = gr.Textbox(label="หรือพิมพ์เอง (Skin)", placeholder="ลายทางสีทอง...")
|
163 |
+
|
164 |
+
with gr.Column():
|
165 |
+
ability_dd = gr.Dropdown(abilities_th, label="พลังพิเศษ (Dropdown)", value=abilities_th[0])
|
166 |
+
ability_tb = gr.Textbox(label="หรือพิมพ์เอง (Ability)", placeholder="สร้างภาพลวงตา...")
|
167 |
+
|
168 |
+
mood_dd = gr.Dropdown(moods_th, label="อารมณ์ (Dropdown)", value=moods_th[0])
|
169 |
+
mood_tb = gr.Textbox(label="หรือพิมพ์เอง (Mood)", placeholder="ขี้เล่นเป็นพิเศษ...")
|
170 |
+
|
171 |
+
# ปุ่มสร้าง + ปุ่ม Copy
|
172 |
+
with gr.Row():
|
173 |
+
create_btn = gr.Button("สร้างมอนสเตอร์!", elem_classes="monster-btn")
|
174 |
+
copy_btn = gr.Button("Copy Prompt", elem_classes="monster-btn")
|
175 |
+
|
176 |
+
monster_desc_th = gr.Textbox(label="รายละเอียด (ภาษาไทย)", interactive=False, elem_id="desc-th")
|
177 |
+
monster_prompt_en = gr.Textbox(label="Prompt (English)", interactive=False, elem_id="prompt-en")
|
178 |
+
|
179 |
+
# Event: กดปุ่ม "สร้างมอนสเตอร์!"
|
180 |
+
create_btn.click(
|
181 |
fn=generate_monster_lab,
|
182 |
+
inputs=[
|
183 |
+
body_dd, body_tb,
|
184 |
+
head_dd, head_tb,
|
185 |
+
arms_dd, arms_tb,
|
186 |
+
skin_dd, skin_tb,
|
187 |
+
ability_dd, ability_tb,
|
188 |
+
mood_dd, mood_tb
|
189 |
+
],
|
190 |
outputs=[monster_desc_th, monster_prompt_en]
|
191 |
)
|
192 |
|
193 |
+
# Event: กดปุ่ม "Copy Prompt" -> ใช้ JS copy to clipboard
|
194 |
+
# inputs: monster_prompt_en (string)
|
195 |
+
# no outputs
|
196 |
+
copy_btn.click(
|
197 |
+
fn=None,
|
198 |
+
_js="function(txt) {navigator.clipboard.writeText(txt);}",
|
199 |
+
inputs=monster_prompt_en,
|
200 |
+
outputs=[]
|
201 |
+
)
|
202 |
+
|
203 |
demo.load(fn=initial_text, inputs=None, outputs=monster_desc_th)
|
204 |
|
205 |
demo.launch()
|