handaru2002 commited on
Commit
4a20f56
·
verified ·
1 Parent(s): 2dadf91

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +61 -116
app.py CHANGED
@@ -1,104 +1,89 @@
1
  # ============================================================
2
- # FINAL SYSTEM
3
- # NLLB + LLaMA + RAG
4
- # Javanese → Indonesian → English
5
  # ============================================================
6
 
7
- import os
8
  import torch
9
  import faiss
10
  import pandas as pd
11
  import gradio as gr
12
- import numpy as np
13
-
14
  from transformers import (
15
  AutoTokenizer,
16
  AutoModelForSeq2SeqLM,
17
- AutoModelForCausalLM,
18
  )
19
- from sentence_transformers import SentenceTransformer
20
 
21
  # ============================================================
22
- # Device
23
  # ============================================================
24
 
25
  device = "cuda" if torch.cuda.is_available() else "cpu"
26
 
27
  # ============================================================
28
- # 1. LOAD NLLB (TRANSLATION ENGINE)
29
  # ============================================================
30
 
31
  NLLB_MODEL = "facebook/nllb-200-distilled-600M"
32
 
33
  nllb_tokenizer = AutoTokenizer.from_pretrained(NLLB_MODEL)
34
- nllb_model = AutoModelForSeq2SeqLM.from_pretrained(NLLB_MODEL)
35
- nllb_model.to(device)
36
  nllb_model.eval()
37
 
38
  JAV = "jav_Latn"
39
  IND = "ind_Latn"
40
- ENG = "eng_Latn"
41
 
42
  # ============================================================
43
- # 2. LOAD LLaMA (REFINEMENT ENGINE)
44
  # ============================================================
45
 
46
- LLAMA_MODEL = "meta-llama/Llama-3.1-8B-Instruct"
 
 
47
 
48
- llama_tokenizer = AutoTokenizer.from_pretrained(LLAMA_MODEL)
49
- llama_model = AutoModelForCausalLM.from_pretrained(
50
- LLAMA_MODEL,
51
- torch_dtype=torch.float16 if device == "cuda" else torch.float32,
52
- device_map="auto"
53
  )
54
- llama_model.eval()
55
 
56
  # ============================================================
57
  # 3. LOAD KNOWLEDGE BASE
58
  # ============================================================
59
 
60
- KB_PATH = "kb_jawa_ngoko_krama_indonesia_100k.csv"
61
-
62
- kb = pd.read_csv(KB_PATH)
63
  kb["jv"] = kb["jv"].astype(str)
64
  kb["id"] = kb["id"].astype(str)
65
 
66
- kb_pairs = list(zip(kb["jv"], kb["id"]))
67
 
68
  # ============================================================
69
- # 4. EMBEDDING + FAISS
70
  # ============================================================
71
 
72
  embedder = SentenceTransformer(
73
  "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
74
  )
75
 
76
- jv_texts = kb["jv"].tolist()
77
- embeddings = embedder.encode(jv_texts, convert_to_numpy=True)
78
 
79
- index = faiss.IndexFlatL2(embeddings.shape[1])
80
- index.add(embeddings)
81
 
82
- # ============================================================
83
- # 5. RETRIEVE PARALLEL PHRASES
84
- # ============================================================
85
-
86
- def retrieve_pairs(jv_text, k=5):
87
- vec = embedder.encode([jv_text])
88
- _, I = index.search(vec, k)
89
-
90
- results = []
91
- for i in I[0]:
92
- jv, idn = kb_pairs[i]
93
- results.append(f"- {jv} → {idn}")
94
-
95
- return "\n".join(results)
96
 
97
  # ============================================================
98
- # 6. NLLB TRANSLATION
99
  # ============================================================
100
 
101
- def nllb_translate(text, tgt_lang):
102
  nllb_tokenizer.src_lang = JAV
103
 
104
  inputs = nllb_tokenizer(
@@ -108,111 +93,71 @@ def nllb_translate(text, tgt_lang):
108
  max_length=512
109
  ).to(device)
110
 
111
- output = nllb_model.generate(
112
  **inputs,
113
- forced_bos_token_id=nllb_tokenizer.convert_tokens_to_ids(tgt_lang),
114
  max_length=256
115
  )
116
 
117
- return nllb_tokenizer.batch_decode(
118
- output, skip_special_tokens=True
119
- )[0]
120
 
121
  # ============================================================
122
- # 7. LLaMA REFINEMENT
123
  # ============================================================
124
 
125
- def llama_refine(raw_translation, rag_context):
126
 
127
  prompt = f"""
128
- Perbaiki terjemahan berikut agar alami dan gramatikal
129
- dalam Bahasa Indonesia.
130
 
131
- Terjemahan mesin:
132
- "{raw_translation}"
133
 
134
- Referensi padanan bahasa:
135
- {rag_context}
136
 
137
- Aturan:
138
- - Hanya keluarkan satu kalimat Bahasa Indonesia
139
- - Jangan menambahkan penjelasan
140
- - Jangan menyebut referensi
141
- - Jangan menambah informasi baru
142
 
143
  Jawaban:
144
  """
145
 
146
- inputs = llama_tokenizer(
147
- prompt,
148
- return_tensors="pt"
149
- ).to(llama_model.device)
150
 
151
- output = llama_model.generate(
152
  **inputs,
153
  max_new_tokens=80,
154
  temperature=0.2,
155
  do_sample=False
156
  )
157
 
158
- text = llama_tokenizer.decode(
159
- output[0],
160
- skip_special_tokens=True
161
- )
162
-
163
  return text.split("Jawaban:")[-1].strip()
164
 
165
  # ============================================================
166
- # 8. PIPELINE UTAMA
167
  # ============================================================
168
 
169
- def translate_pipeline(jv_text):
170
-
171
- # Step 1 — Raw translation
172
- raw_id = nllb_translate(jv_text, IND)
173
-
174
- # Step 2 — RAG retrieval
175
- rag_context = retrieve_pairs(jv_text)
176
-
177
- # Step 3 — LLaMA refinement
178
- final_id = llama_refine(raw_id, rag_context)
179
-
180
- # Step 4 — English (optional)
181
- final_en = nllb_translate(final_id, ENG)
182
-
183
- return final_id, final_en
184
 
185
  # ============================================================
186
- # 9. GRADIO UI
187
  # ============================================================
188
 
189
- with gr.Blocks(title="NLLB + LLaMA + RAG Translator") as demo:
 
190
 
191
- gr.Markdown("""
192
- ## 🌾 Translator Bahasa Jawa
193
- **NLLB + LLaMA + RAG (Parallel Corpus)**
194
 
195
- Low-resource language
196
- Linguistically grounded
197
- ✔ Research-grade architecture
198
- """)
199
 
200
- inp = gr.Textbox(
201
- label="Input Bahasa Jawa",
202
- lines=4,
203
- placeholder="Kula badhe sowan dhateng griya eyang."
204
- )
205
-
206
- out_id = gr.Textbox(label="Bahasa Indonesia", lines=4)
207
- out_en = gr.Textbox(label="English", lines=4)
208
-
209
- btn = gr.Button("🔄 Terjemahkan")
210
- btn.click(translate_pipeline, inp, [out_id, out_en])
211
-
212
- demo.launch(
213
- server_name="0.0.0.0",
214
- server_port=7860,
215
- ssr_mode=False
216
- )
217
 
218
 
 
1
  # ============================================================
2
+ # FINAL TRANSLATION SYSTEM
3
+ # NLLB + RAG + OPEN LLM (NO GATED MODEL)
 
4
  # ============================================================
5
 
 
6
  import torch
7
  import faiss
8
  import pandas as pd
9
  import gradio as gr
10
+ from sentence_transformers import SentenceTransformer
 
11
  from transformers import (
12
  AutoTokenizer,
13
  AutoModelForSeq2SeqLM,
14
+ AutoModelForCausalLM
15
  )
 
16
 
17
  # ============================================================
18
+ # DEVICE
19
  # ============================================================
20
 
21
  device = "cuda" if torch.cuda.is_available() else "cpu"
22
 
23
  # ============================================================
24
+ # 1. NLLB TRANSLATION MODEL
25
  # ============================================================
26
 
27
  NLLB_MODEL = "facebook/nllb-200-distilled-600M"
28
 
29
  nllb_tokenizer = AutoTokenizer.from_pretrained(NLLB_MODEL)
30
+ nllb_model = AutoModelForSeq2SeqLM.from_pretrained(NLLB_MODEL).to(device)
 
31
  nllb_model.eval()
32
 
33
  JAV = "jav_Latn"
34
  IND = "ind_Latn"
 
35
 
36
  # ============================================================
37
+ # 2. OPEN LLM (REPLACEMENT FOR LLAMA)
38
  # ============================================================
39
 
40
+ LLM_MODEL = "mistralai/Mistral-7B-Instruct-v0.2"
41
+ # alternatif:
42
+ # "Qwen/Qwen2.5-7B-Instruct"
43
 
44
+ llm_tokenizer = AutoTokenizer.from_pretrained(LLM_MODEL)
45
+ llm_model = AutoModelForCausalLM.from_pretrained(
46
+ LLM_MODEL,
47
+ device_map="auto",
48
+ torch_dtype=torch.float16 if device == "cuda" else torch.float32
49
  )
50
+ llm_model.eval()
51
 
52
  # ============================================================
53
  # 3. LOAD KNOWLEDGE BASE
54
  # ============================================================
55
 
56
+ kb = pd.read_csv("kb_jawa_ngoko_krama_indonesia_100k.csv")
 
 
57
  kb["jv"] = kb["jv"].astype(str)
58
  kb["id"] = kb["id"].astype(str)
59
 
60
+ pairs = list(zip(kb["jv"], kb["id"]))
61
 
62
  # ============================================================
63
+ # 4. FAISS RAG
64
  # ============================================================
65
 
66
  embedder = SentenceTransformer(
67
  "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
68
  )
69
 
70
+ emb = embedder.encode(kb["jv"].tolist(), convert_to_numpy=True)
 
71
 
72
+ index = faiss.IndexFlatL2(emb.shape[1])
73
+ index.add(emb)
74
 
75
+ def retrieve(text, k=5):
76
+ v = embedder.encode([text])
77
+ _, I = index.search(v, k)
78
+ return "\n".join(
79
+ [f"- {pairs[i][0]} → {pairs[i][1]}" for i in I[0]]
80
+ )
 
 
 
 
 
 
 
 
81
 
82
  # ============================================================
83
+ # 5. NLLB TRANSLATE
84
  # ============================================================
85
 
86
+ def nllb_translate(text):
87
  nllb_tokenizer.src_lang = JAV
88
 
89
  inputs = nllb_tokenizer(
 
93
  max_length=512
94
  ).to(device)
95
 
96
+ out = nllb_model.generate(
97
  **inputs,
98
+ forced_bos_token_id=nllb_tokenizer.convert_tokens_to_ids(IND),
99
  max_length=256
100
  )
101
 
102
+ return nllb_tokenizer.decode(out[0], skip_special_tokens=True)
 
 
103
 
104
  # ============================================================
105
+ # 6. LLM REFINEMENT
106
  # ============================================================
107
 
108
+ def refine(raw, context):
109
 
110
  prompt = f"""
111
+ Perbaiki terjemahan berikut agar alami dalam Bahasa Indonesia.
 
112
 
113
+ Terjemahan awal:
114
+ {raw}
115
 
116
+ Referensi padanan:
117
+ {context}
118
 
119
+ Instruksi:
120
+ - Hasilkan satu kalimat Bahasa Indonesia
121
+ - Jangan memberi penjelasan
 
 
122
 
123
  Jawaban:
124
  """
125
 
126
+ inputs = llm_tokenizer(prompt, return_tensors="pt").to(llm_model.device)
 
 
 
127
 
128
+ output = llm_model.generate(
129
  **inputs,
130
  max_new_tokens=80,
131
  temperature=0.2,
132
  do_sample=False
133
  )
134
 
135
+ text = llm_tokenizer.decode(output[0], skip_special_tokens=True)
 
 
 
 
136
  return text.split("Jawaban:")[-1].strip()
137
 
138
  # ============================================================
139
+ # 7. PIPELINE
140
  # ============================================================
141
 
142
+ def pipeline(jv_text):
143
+ raw = nllb_translate(jv_text)
144
+ ctx = retrieve(jv_text)
145
+ final = refine(raw, ctx)
146
+ return final
 
 
 
 
 
 
 
 
 
 
147
 
148
  # ============================================================
149
+ # 8. UI
150
  # ============================================================
151
 
152
+ with gr.Blocks() as demo:
153
+ gr.Markdown("## 🌾 NLLB + RAG + Open LLM Translator")
154
 
155
+ inp = gr.Textbox(label="Bahasa Jawa", lines=4)
156
+ out = gr.Textbox(label="Bahasa Indonesia", lines=4)
 
157
 
158
+ btn = gr.Button("Terjemahkan")
159
+ btn.click(pipeline, inp, out)
 
 
160
 
161
+ demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
 
163