File size: 6,125 Bytes
a7ae484
 
0b17de3
e23b077
ee0bd29
 
a7ae484
 
 
 
 
0b17de3
a7ae484
 
 
ee0bd29
a7ae484
 
 
3de552f
 
 
e23b077
3de552f
e23b077
 
3de552f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e23b077
 
321de1f
6bad34a
8862c6c
e23b077
 
 
 
 
a7ae484
ee0bd29
 
8862c6c
3de552f
 
 
 
8862c6c
ee0bd29
a7ae484
 
321de1f
eddbdb5
 
321de1f
e23b077
 
78bd309
 
 
 
 
 
 
 
 
 
e23b077
 
321de1f
eddbdb5
 
 
 
 
eb91f61
ee0bd29
eb91f61
 
 
 
 
 
 
 
ee0bd29
 
3de552f
 
 
81dc1ea
 
ee0bd29
e23b077
3de552f
 
 
81dc1ea
 
 
 
e014c23
ee0bd29
 
 
 
 
 
e23b077
1fdefa0
9802cb1
321de1f
9802cb1
ee0bd29
 
8862c6c
 
ee0bd29
9802cb1
 
 
8862c6c
9802cb1
ee0bd29
 
 
321de1f
ee0bd29
9802cb1
ee0bd29
321de1f
ee0bd29
a7ae484
 
ee0bd29
321de1f
 
ee0bd29
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import gradio as gr
import torch
import spaces
import re
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
from threading import Thread

model_name = "Pyefuri/Qwen2.5-3B-Bahasa-Biak-Final"

print("Memuat tokenizer...")
tokenizer = AutoTokenizer.from_pretrained(model_name)

print("Memuat model Bahasa Biak...")
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    dtype=torch.float16,
    device_map="auto"
)

# =====================================================================
# MODIFIKASI 1: Fungsi interseptor sapaan yang lebih fleksibel (Regex)
# =====================================================================
def cek_sapaan_otomatis(message):
    # Menghapus tanda baca dan mengubah ke huruf kecil
    teks_bersih = re.sub(r'[^\w\s]', '', message.strip().lower())
    
    # Deteksi variasi sapaan dasar secara parsial (termasuk salah ketik seperti hala/helo)
    apakah_menyapa = any(kata in teks_bersih for kata in ["halo", "hala", "hai", "helo", "hi", "p "])
    
    # Deteksi waktu
    apakah_malam = "malam" in teks_bersih
    apakah_pagi = "pagi" in teks_bersih
    apakah_siang = "siang" in teks_bersih
    apakah_sore = "sore" in teks_bersih
    
    # Logika penentu respon instan Bahasa Indonesia
    if apakah_malam or (apakah_menyapa and apakah_malam):
        return "Halo, selamat malam juga! Ada yang bisa saya bantu untuk diterjemahkan ke Bahasa Biak?"
    elif apakah_pagi or (apakah_menyapa and apakah_pagi):
        return "Halo, selamat pagi juga! Ada yang bisa saya bantu hari ini?"
    elif apakah_siang or (apakah_menyapa and apakah_siang):
        return "Halo, selamat siang juga! Ada yang bisa saya bantu?"
    elif apakah_sore or (apakah_menyapa and apakah_sore):
        return "Halo, selamat sore juga! Ada yang bisa saya bantu?"
    elif apakah_menyapa or teks_bersih == "p":
        return "Halo! Ada yang bisa saya bantu untuk diterjemahkan ke Bahasa Biak?"
        
    return None

# Fungsi utama penerjemah dan chat di GPU
@spaces.GPU
def prediksi_terjemahan(message, history):
    respon_sapaan = cek_sapaan_otomatis(message)
    if respon_sapaan:
        yield respon_sapaan
        return

    percakapan = [
        {
            "role": "system", 
            "content": (
                "Kamu adalah asisten AI yang ramah. Kamu menguasai Bahasa Indonesia dan Bahasa Biak. "
                "Aturan interaksi:\n"
                "1. Jika pengguna menyapa (seperti 'halo', 'selamat malam') atau bertanya umum, balaslah dengan ramah menggunakan Bahasa Indonesia.\n"
                "2. Jika pengguna meminta terjemahan atau memasukkan kalimat untuk diartikan ke Bahasa Biak, berikan hasil terjemahan yang akurat."
            )
        }
    ]
    
    # Memproses history format Gradio 6.0 (List of Dictionaries)
    if history:
        for interaksi in history:
            if isinstance(interaksi, dict):
                role = interaksi.get("role")
                content = interaksi.get("content")
                
                # --- BERIKUT ADALAH PENAMBAHAN MODUL PEMBERSIH UNTUK GRADIO 6.0 ---
                if isinstance(content, list):
                    teks_murni = ""
                    for item in content:
                        if isinstance(item, dict) and "text" in item:
                            teks_murni += item["text"]
                    content = teks_murni
                # ------------------------------------------------------------------
                
                if role and content:
                    percakapan.append({"role": role, "content": str(content)})
            elif isinstance(interaksi, (list, tuple)) and len(interaksi) == 2:
                human, assistant = interaksi
                if human:
                    percakapan.append({"role": "user", "content": str(human)})
                if assistant:
                    percakapan.append({"role": "assistant", "content": str(assistant)})
    
    percakapan.append({"role": "user", "content": message})
    
    input_text = tokenizer.apply_chat_template(
        percakapan,
        tokenize=False,
        add_generation_prompt=True
    )
    
    inputs = tokenizer([input_text], return_tensors="pt").to(model.device)
    streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
    
    # =====================================================================
    # MODIFIKASI 2: Penyesuaian hyperparameter agar Qwen lebih luwes chitchat
    # =====================================================================
    generation_kwargs = dict(
        **inputs,
        streamer=streamer,
        max_new_tokens=256,
        temperature=0.6,      # Diubah ke 0.6 agar tidak terlalu kaku saat mengobrol biasa
        top_p=0.9,            # Diubah ke 0.9 untuk memberikan variasi kosakata dasar yang lebih natural
        repetition_penalty=1.1, # Diturunkan ke 1.1 agar kalimat mengalir lebih baik
        do_sample=True,
        eos_token_id=tokenizer.eos_token_id,
        pad_token_id=tokenizer.pad_token_id if tokenizer.pad_token_id is not None else tokenizer.eos_token_id
    )
    
    thread = Thread(target=model.generate, kwargs=generation_kwargs)
    thread.start()
    
    text_terjemahan = ""
    for new_text in streamer:
        text_terjemahan += new_text
        yield text_terjemahan

# ========================================================
#  UI/UX CONFIGURATION (COMPATIBLE WITH GRADIO 6.0)
# ========================================================
desain_kustom_css = """
#wadah-lebar-chat {
    max-width: 800px !important;
    margin: 0 auto !important;
    float: none !important;
    padding-top: 20px;
}
.judul-pusat {
    text-align: center !important;
    margin-bottom: 15px !important;
}
"""

with gr.Blocks() as demo:
    with gr.Column(elem_id="wadah-lebar-chat"):
        gr.Markdown("# 🤖 AI Bahasa Indonesia-Biak", elem_classes="judul-pusat")
        gr.ChatInterface(
            fn=prediksi_terjemahan
        )

if __name__ == "__main__":
    demo.launch(
        theme=gr.themes.Soft(),
        css=desain_kustom_css
    )