zenityx's picture
Update app.py
4ce32cc verified
raw
history blame
12.4 kB
import gradio as gr
import random
# ==== เพิ่ม: โหลดโมเดล MarianMT และ Tokenizer สำหรับแปลไทย->อังกฤษ ====
from transformers import MarianMTModel, MarianTokenizer
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:
"""
ใช้โมเดล MarianMT แปลภาษาไทย -> อังกฤษ
รันบน CPU (Hugging Face Spaces) ได้โดยไม่ต้องใช้ GPU
"""
th_text = th_text.strip()
if not th_text:
return ""
inputs = tokenizer(th_text, return_tensors="pt", max_length=512, truncation=True)
translation_tokens = model.generate(**inputs, max_length=512)
en_text = tokenizer.decode(translation_tokens[0], skip_special_tokens=True)
return en_text
##############################################
# ฟังก์ชันคำนวณ: อุณหภูมิ & แรงโน้มถ่วง
##############################################
def approximate_temperature(planet_type, distance_au):
if planet_type == "ดาวหิน (Rocky Planet)":
base_temp = 15
elif planet_type == "ดาวก๊าซ (Gas Giant)":
base_temp = 30
elif planet_type == "ดาวน้ำแข็ง (Icy Planet)":
base_temp = -50
else:
base_temp = 0
if distance_au > 1.0:
diff = (distance_au - 1.0) * 20
approx_temp = base_temp - diff
else:
diff = (1.0 - distance_au) * 30
approx_temp = base_temp + diff
return round(approx_temp)
def approximate_gravity(diameter_earth):
return round(diameter_earth, 2)
##############################################
# สรุปข้อมูล (ภาษาไทย) สำหรับเด็ก
##############################################
def child_friendly_summary(
name_th, planet_type_th, temp_c, gravity_g, oxygen_percent, life_th
):
if temp_c > 40:
temp_comment = "ร้อนจัดเลย!"
elif temp_c < -10:
temp_comment = "หนาวสุดขั้ว!"
else:
temp_comment = "อากาศกำลังดีเลย!"
if gravity_g > 1.5:
gravity_comment = f"แรงโน้มถ่วงประมาณ {gravity_g}g อาจเดินลำบากนะ!"
elif gravity_g < 0.5:
gravity_comment = f"แรงโน้มถ่วงแค่ {gravity_g}g ระวังลอยได้!"
else:
gravity_comment = f"แรงโน้มถ่วง ~{gravity_g}g กำลังโอเค"
o2_comment = f"ออกซิเจน {oxygen_percent}%"
summary_th = (
f"ดาว {name_th} เป็น{planet_type_th}\n"
f"อุณหภูมิราว {temp_c}°C ({temp_comment})\n"
f"{gravity_comment}\n"
f"บรรยากาศมี {o2_comment}\n"
f"มีสิ่งมีชีวิต: {life_th}\n"
f"ว้าว! น่าสนใจมาก!"
)
return summary_th
##############################################
# ฟังก์ชันสร้าง 3 Prompts (ภาษาอังกฤษ)
##############################################
def generate_three_prompts_en(
planet_name_en, planet_type_en, distance_au, diameter_factor,
temp_c, gravity_g, oxygen_percent, life_en
):
base_info = (
f"Planet {planet_name_en}, {planet_type_en}, at ~{distance_au} AU from its star, "
f"diameter ~{diameter_factor}x Earth, surface temp ~{temp_c}C, gravity ~{gravity_g}g, "
f"oxygen ~{oxygen_percent}%. "
)
# Prompt 1: ภาพดาวจากอวกาศ
prompt1 = (
f"{base_info}A breathtaking orbital view of this planet showing its vibrant atmosphere, "
f"highly detailed, cinematic lighting, wide shot --ar 16:9"
)
# Prompt 2: สิ่งมีชีวิต
prompt2 = (
f"{base_info}Alien life form on the planet: {life_en}, "
f"illustration focusing on creature design, environment details, "
f"fantasy concept art, photorealistic --ar 9:16"
)
# Prompt 3: พื้นผิวดาว
prompt3 = (
f"{base_info}Planetary surface landscape, unique terrain and color palette, "
f"epic environment shot, detailed textures, natural light, hyperrealistic --ar 16:9"
)
return prompt1, prompt2, prompt3
##############################################
# ฟังก์ชันหลัก (รับ input ไทย -> สร้างผลลัพธ์)
##############################################
def generate_planet_info(
planet_name_th, # ชื่อดาว (ไทย)
planet_type_th, # ชนิดดาว (ไทย)
distance_str, # ระยะห่าง (string)
diameter_str, # ขนาด (string)
oxygen_percent, # slider (int)
life_th # สิ่งมีชีวิต (ไทย)
):
# parse float
try:
distance_au = float(distance_str)
except:
distance_au = 1.0
try:
diameter_factor = float(diameter_str)
except:
diameter_factor = 1.0
# คำนวณ
temp_c = approximate_temperature(planet_type_th, distance_au)
gravity_g = approximate_gravity(diameter_factor)
# 1) สรุปสำหรับเด็ก (ภาษาไทย)
child_summary = child_friendly_summary(
planet_name_th, planet_type_th, temp_c,
gravity_g, oxygen_percent, life_th
)
# 2) รายละเอียด (ไทย)
detail_th = (
f"ชื่อดาวเคราะห์: {planet_name_th}\n"
f"ชนิดดาว: {planet_type_th}\n"
f"ระยะห่าง: ~{distance_au} AU\n"
f"ขนาด: ~{diameter_factor} เท่าโลก\n"
f"อุณหภูมิ: ~{temp_c} °C\n"
f"แรงโน้มถ่วง: ~{gravity_g} g\n"
f"เปอร์เซ็นต์ออกซิเจน: {oxygen_percent}%\n"
f"สิ่งมีชีวิต: {life_th}\n"
)
# 3) แปลเป็นอังกฤษผ่าน MarianMT
planet_name_en = translate_th_to_en(planet_name_th)
# แปล life_th ด้วย
life_en = translate_th_to_en(life_th)
# แมปชนิดดาว -> อังกฤษ
type_map = {
"ดาวหิน (Rocky Planet)": "rocky planet",
"ดาวก๊าซ (Gas Giant)": "gas giant",
"ดาวน้ำแข็ง (Icy Planet)": "icy planet",
}
planet_type_en = type_map.get(planet_type_th, "mysterious planet")
# 4) สร้าง 3 prompts
prompt1, prompt2, prompt3 = generate_three_prompts_en(
planet_name_en, planet_type_en, distance_au, diameter_factor,
temp_c, gravity_g, oxygen_percent, life_en
)
prompt_all = (
f"--- Prompt #1 ---\n{prompt1}\n\n"
f"--- Prompt #2 ---\n{prompt2}\n\n"
f"--- Prompt #3 ---\n{prompt3}\n"
)
return child_summary, detail_th, prompt_all
##############################################
# ส่วน UI (Gradio)
##############################################
import gradio as gr
css_code = """
body {
background-color: #F9FBFF;
font-family: "Kanit", sans-serif;
}
#title {
color: #4A90E2;
text-align: center;
font-size: 2rem;
margin-top: 20px;
margin-bottom: 10px;
font-weight: bold;
}
.game-desc {
margin: 0 auto;
width: 90%;
background-color: #ECF6FF;
border: 2px dashed #B3DAFF;
border-radius: 10px;
padding: 15px;
color: #333;
margin-bottom: 20px;
}
.btn-main {
background-color: #FFE066;
border: 2px solid #FFCA28;
font-weight: bold;
font-size: 1.1rem;
padding: 10px 30px;
border-radius: 10px;
margin-right: 10px;
}
#child-summary, #detail-th, #prompt-en {
background-color: #FFFDF5;
border: 2px solid #FFE082;
border-radius: 10px;
padding: 10px;
margin-bottom: 20px;
}
"""
def welcome_text():
return "ยินดีต้อนรับสู่ Planetary Adventure! ลองกรอกข้อมูลแล้วกด 'สร้างโลกแฟนตาซี' สิ!"
copy_button_html = """
<button style="background-color: #F06292; border: 2px solid #E91E63; font-weight: bold;
font-size: 1.0rem; padding: 8px 20px; border-radius: 10px;"
onclick="copyPromptText()">
คัดลอก Prompt
</button>
<script>
function copyPromptText() {
const promptBox = document.querySelector('#prompt-en textarea');
if (!promptBox) {
alert('ไม่พบข้อความ Prompt!');
return;
}
const promptText = promptBox.value;
navigator.clipboard.writeText(promptText);
alert('คัดลอก Prompt แล้ว! เอาไปใช้กับ Midjourney ได้เลย~');
}
</script>
"""
with gr.Blocks(css=css_code) as demo:
gr.Markdown("<h1 id='title'>Planetary Adventure (Thai + %O2 + 3 English Prompts w/ Real Translation)</h1>")
gr.Markdown("""
<div class="game-desc">
<p>ออกแบบดาวเคราะห์ในฝันของหนูน้อย (ภาษาไทย) แล้วให้ระบบแปลเป็นอังกฤษผ่าน MarianMT!</p>
<ul>
<li>กรอกชื่อดาว, ชนิดดาว, ระยะห่าง, ขนาด (เท่าโลก)</li>
<li>เลื่อน %O2 ในบรรยากาศ</li>
<li>พิมพ์สิ่งมีชีวิตเป็นภาษาไทย</li>
<li>กดปุ่ม <strong>"สร้างโลกแฟนตาซี"</strong></li>
</ul>
<p>รับ <em>สรุปสำหรับเด็ก</em> (ไทย), <em>รายละเอียด</em> (ไทย), และ <em>3 Prompts อังกฤษ</em> นำไปใช้ใน Midjourney ได้ทันที!</p>
</div>
""")
planet_name_th = gr.Textbox(label="ชื่อดาวเคราะห์ (ภาษาไทย)", placeholder="ตัวอย่าง: ดาวซานาดา")
planet_type_th = gr.Dropdown(
label="ชนิดดาว",
choices=["ดาวหิน (Rocky Planet)", "ดาวก๊าซ (Gas Giant)", "ดาวน้ำแข็ง (Icy Planet)"],
value="ดาวหิน (Rocky Planet)"
)
distance_au = gr.Textbox(label="ระยะห่างจากดาวฤกษ์ (หน่วย AU)", placeholder="เช่น 0.8, 1, 2")
diameter_factor = gr.Textbox(label="ขนาด (เท่าเส้นผ่านศูนย์กลางโลก)", placeholder="เช่น 1, 2, 0.5")
oxygen_slider = gr.Slider(
minimum=0,
maximum=100,
step=1,
value=21,
label="% ออกซิเจนในบรรยากาศ"
)
life_th = gr.Textbox(label="สิ่งมีชีวิตบนดาว (ภาษาไทย)", placeholder="ตัวอย่าง: สัตว์เลื้อยคลานขนาดยักษ์")
create_btn = gr.Button("สร้างโลกแฟนตาซี", elem_classes="btn-main")
child_summary_out = gr.Textbox(label="สรุป (สำหรับเด็ก)", interactive=False, elem_id="child-summary")
detail_th_out = gr.Textbox(label="รายละเอียด (ภาษาไทย)", interactive=False, elem_id="detail-th")
prompt_en_out = gr.Textbox(label="3 Prompts (English)", interactive=False, elem_id="prompt-en")
gr.HTML(copy_button_html)
create_btn.click(
fn=generate_planet_info,
inputs=[
planet_name_th,
planet_type_th,
distance_au,
diameter_factor,
oxygen_slider,
life_th
],
outputs=[child_summary_out, detail_th_out, prompt_en_out]
)
demo.load(fn=welcome_text, inputs=None, outputs=child_summary_out)
demo.launch()