Spaces:
Running
Running
import gradio as gr | |
from transformers import MarianMTModel, MarianTokenizer | |
# ============================== | |
# 1) โหลดโมเดลแปลภาษา (MarianMT) จาก Hugging Face | |
# ใช้โมเดล "Helsinki-NLP/opus-mt-th-en" | |
# ============================== | |
model_name = "Helsinki-NLP/opus-mt-th-en" | |
tokenizer = MarianTokenizer.from_pretrained(model_name) | |
model = MarianMTModel.from_pretrained(model_name) | |
def translate_th_to_en(th_text: str) -> str: | |
""" | |
แปลข้อความภาษาไทยเป็นอังกฤษ ใช้ MarianMTModel แบบ Offline | |
""" | |
th_text = th_text.strip() | |
if not th_text: | |
return "" | |
# สร้าง input token | |
inputs = tokenizer(th_text, return_tensors="pt", max_length=512, truncation=True) | |
# สร้าง output token (การแปล) | |
translation_tokens = model.generate(**inputs, max_length=512) | |
# ถอดรหัสเป็น string | |
en_text = tokenizer.decode(translation_tokens[0], skip_special_tokens=True) | |
return en_text | |
# ============================== | |
# 2) ตัวเลือก (ภาษาไทย) สำหรับมอนสเตอร์ | |
# ============================== | |
body_shapes_th = [ | |
"ตัวเหนียวขยุกขยิก", "ตัวปุกปุยกลม", "ตัวเต็มไปด้วยหนาม", | |
"ตัวเล็กเหมือนแมลง", "ตัวโปร่งแสงลอยได้" | |
] | |
heads_th = [ | |
"หัวตาเดียว", "หัวสองเขาเหมือนมังกร", "หัวมีเขาใหญ่มาก", | |
"หัวผีแสยะยิ้ม", "หัวกระต่ายน่ารัก" | |
] | |
arms_legs_th = [ | |
"แขนหนวดปลาหมึกและขาปลาหมึก", "แขนกลและเท้าสเก็ต", | |
"ปีกขนนกและอุ้งเท้าสิงโต", "แขนเรืองแสงและขายานโฮเวอร์", | |
"แขนไม้หุ่นเชิดและขายักษ์แมงมุม" | |
] | |
skin_patterns_th = [ | |
"ลายสีรุ้ง", "จุดม่วงเรืองแสง", "เกล็ดเหล็ก", | |
"ขนนกวิบวับ", "จุดกลมกากเพชร" | |
] | |
abilities_th = [ | |
"พ่นไฟ", "ปล่อยฟองสบู่", "ควบคุมสายฟ้า", | |
"ร้องเพลงกล่อม", "วาร์ประยะสั้น" | |
] | |
moods_th = [ | |
"เป็นมิตร", "ขี้หงุดหงิด", "ตลกโปกฮา", | |
"ซนเป็นลิง", "ขี้อาย" | |
] | |
# ============================== | |
# 3) ฟังก์ชันสร้าง Prompt | |
# ============================== | |
def generate_monster_lab(body_th, head_th, arms_th, skin_th, ability_th, mood_th): | |
""" | |
สร้าง 'รายละเอียดมอนสเตอร์ (ภาษาไทย)' + Prompt ภาษาอังกฤษ | |
""" | |
# (a) รวมรายละเอียดมอนสเตอร์ (ภาษาไทย) | |
desc_th = ( | |
f"มอนสเตอร์อารมณ์{mood_th} มี{body_th} " | |
f"พร้อมด้วย{head_th}, {arms_th}, " | |
f"ผิว/ลายแบบ{skin_th}, และพลังพิเศษคือ{ability_th}!" | |
) | |
# (b) แปลทีละส่วน | |
body_en = translate_th_to_en(body_th) | |
head_en = translate_th_to_en(head_th) | |
arms_en = translate_th_to_en(arms_th) | |
skin_en = translate_th_to_en(skin_th) | |
ability_en = translate_th_to_en(ability_th) | |
mood_en = translate_th_to_en(mood_th) | |
# (c) ประกอบประโยคภาษาอังกฤษง่าย ๆ | |
# 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]!" | |
prompt_en = ( | |
f"This is a {mood_en} monster with {body_en}, " | |
f"a {head_en}, {arms_en}, covered in {skin_en} skin, " | |
f"and it can {ability_en}!" | |
) | |
return desc_th, prompt_en | |
# ============================== | |
# 4) สร้าง UI (Gradio) | |
# ============================== | |
css_code = """ | |
body { | |
background-color: #FFF7EA; | |
font-family: "Kanit", sans-serif; | |
} | |
#title { | |
color: #FF6F91; | |
text-align: center; | |
font-size: 2rem; | |
margin-top: 20px; | |
margin-bottom: 10px; | |
font-weight: bold; | |
} | |
.game-desc { | |
margin: 0 auto; | |
width: 80%; | |
background-color: #FFF2F0; | |
border: 2px dashed #FAB1A0; | |
border-radius: 10px; | |
padding: 15px; | |
color: #333; | |
} | |
.monster-btn { | |
background-color: #FFC107; | |
border: 2px solid #FFA000; | |
font-weight: bold; | |
font-size: 1.1rem; | |
padding: 10px 20px; | |
border-radius: 10px; | |
} | |
.monster-btn:hover { | |
background-color: #FFD54F; | |
} | |
#desc-th, #prompt-en { | |
background-color: #FFFAE6; | |
border: 2px solid #FFE082; | |
border-radius: 10px; | |
padding: 10px; | |
margin-bottom: 20px; | |
} | |
""" | |
def initial_text(): | |
""" | |
แสดงข้อความเริ่มต้นเมื่อเปิดเว็บครั้งแรก | |
""" | |
return "ยังไม่ได้สร้างมอนสเตอร์นะจ๊ะ เลือกค่าต่าง ๆ แล้วกด 'สร้างมอนสเตอร์!' ดูสิ" | |
with gr.Blocks(css=css_code) as demo: | |
gr.Markdown("<h1 id='title'>ZenityX Monster Lab (Thai -> English)</h1>") | |
gr.Markdown( | |
""" | |
<div class="game-desc"> | |
<p><strong>วิธีเล่น:</strong></p> | |
<ol> | |
<li>เลือกค่าต่าง ๆ ของมอนสเตอร์ (ภาษาไทย)</li> | |
<li>กดปุ่ม <strong>"สร้างมอนสเตอร์!"</strong></li> | |
<li>ชม <u>รายละเอียดมอนสเตอร์ (ภาษาไทย)</u> และ <u>Prompt ภาษาอังกฤษ</u> สำหรับ AI</li> | |
</ol> | |
<p>ลองเลยจ้า! (โมเดล "Helsinki-NLP/opus-mt-th-en" ทำงานออฟไลน์ได้ใน Hugging Face Spaces)</p> | |
</div> | |
""" | |
) | |
# Dropdown หรือจะปรับเป็น Textbox ก็ได้ | |
dd_body = gr.Dropdown(label="รูปร่างมอนสเตอร์", choices=body_shapes_th, value=body_shapes_th[0]) | |
dd_head = gr.Dropdown(label="หัว/ใบหน้า", choices=heads_th, value=heads_th[0]) | |
dd_arms = gr.Dropdown(label="แขนขา", choices=arms_legs_th, value=arms_legs_th[0]) | |
dd_skin = gr.Dropdown(label="สีผิว/ลวดลาย", choices=skin_patterns_th, value=skin_patterns_th[0]) | |
dd_ability = gr.Dropdown(label="พลังพิเศษ", choices=abilities_th, value=abilities_th[0]) | |
dd_mood = gr.Dropdown(label="อารมณ์/บุคลิก", choices=moods_th, value=moods_th[0]) | |
create_button = gr.Button("สร้างมอนสเตอร์!", elem_classes="monster-btn") | |
monster_desc_th = gr.Textbox(label="รายละเอียดมอนสเตอร์ (ภาษาไทย)", interactive=False, elem_id="desc-th") | |
monster_prompt_en = gr.Textbox(label="Prompt ภาษาอังกฤษ (สำหรับ AI)", interactive=False, elem_id="prompt-en") | |
# เมื่อกดปุ่ม -> เรียก generate_monster_lab | |
create_button.click( | |
fn=generate_monster_lab, | |
inputs=[dd_body, dd_head, dd_arms, dd_skin, dd_ability, dd_mood], | |
outputs=[monster_desc_th, monster_prompt_en] | |
) | |
# เมื่อโหลดเว็บครั้งแรก | |
demo.load(fn=initial_text, inputs=None, outputs=monster_desc_th) | |
demo.launch() | |