MuhammadKhoirul010 commited on
Commit
20e6cf6
·
verified ·
1 Parent(s): 2276b0d

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +228 -0
app.py ADDED
@@ -0,0 +1,228 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from transformers import pipeline, T5Tokenizer, T5ForConditionalGeneration, AutoTokenizer, AutoModelForSeq2SeqLM
3
+ import torch
4
+ import evaluate # Untuk evaluasi ROUGE
5
+ import pandas as pd # Untuk membuat DataFrame untuk tabel hasil evaluasi
6
+ import io # Untuk download file
7
+
8
+ rouge_metric = evaluate.load("rouge")
9
+
10
+ # ---------- LOAD MODELS ----------
11
+ # Fungsi untuk memuat model T5 Bahasa Indonesia
12
+ def load_t5_indonesian_model():
13
+ try:
14
+ t5_tokenizer = T5Tokenizer.from_pretrained("cahya/t5-base-indonesian-summarization-cased")
15
+ t5_model = T5ForConditionalGeneration.from_pretrained("cahya/t5-base-indonesian-summarization-cased")
16
+
17
+ # Pindahkan model ke GPU jika tersedia
18
+ t5_device = 0 if torch.cuda.is_available() else -1
19
+ if t5_device != -1:
20
+ t5_model.to(f"cuda:{t5_device}")
21
+
22
+ print("Model T5 Bahasa Indonesia (cahya/t5) berhasil dimuat.")
23
+ return t5_tokenizer, t5_model, t5_device
24
+ except Exception as e:
25
+ print(f"Error saat memuat model T5 Bahasa Indonesia: {str(e)}")
26
+ return None, None, -1
27
+
28
+ # Fungsi untuk memuat model IndoBART v2
29
+ def load_indobart_model():
30
+ try:
31
+ # Menggunakan pipeline untuk IndoBART
32
+ indobart_pipeline = pipeline("summarization", model="gaduhhartawan/indobart-base-v2")
33
+ print("Model IndoBART v2 (gaduhhartawan/indobart) berhasil dimuat.")
34
+ return indobart_pipeline
35
+ except Exception as e:
36
+ print(f"Error saat memuat model IndoBART v2: {str(e)}")
37
+ return None
38
+
39
+ # Muat kedua model saat aplikasi dimulai
40
+ # Ini akan dimuat hanya sekali ketika script dijalankan
41
+ t5_tokenizer, t5_model, t5_device = load_t5_indonesian_model()
42
+ indobart_summarizer_pipeline = load_indobart_model()
43
+
44
+ # ---------- SUMMARIZATION AND EVALUATION FUNCTION ----------
45
+ def summarize_and_evaluate(text_input, model_choice, min_length_val=30, max_length_val=150, reference_summary=""):
46
+ summarized_text = ""
47
+ status_message = ""
48
+ current_model_name = ""
49
+
50
+ if not text_input.strip():
51
+ return "⚠️ Mohon masukkan teks yang ingin diringkas!", "", "", ""
52
+
53
+ if min_length_val >= max_length_val:
54
+ return "⚠️ Panjang minimum harus lebih kecil dari panjang maksimum!", "", "", ""
55
+ if min_length_val <= 0 or max_length_val <= 0:
56
+ return "⚠️ Panjang tidak boleh nol atau negatif!", "", "", ""
57
+
58
+ try:
59
+ if model_choice == "cahya/t5-base-indonesian-summarization-cased":
60
+ current_model_name = "T5 Bahasa Indonesia (cahya/t5)"
61
+ if t5_tokenizer is None or t5_model is None:
62
+ status_message = f"❌ Error: {current_model_name} gagal dimuat."
63
+ else:
64
+ # Tokenisasi dengan prefix dan truncation untuk T5
65
+ input_ids = t5_tokenizer.encode("summarize: " + text_input,
66
+ return_tensors="pt",
67
+ max_length=512, # Batasi panjang input token T5 (umumnya 512)
68
+ truncation=True)
69
+
70
+ # Pindahkan input_ids ke GPU jika model ada di GPU
71
+ if t5_device != -1:
72
+ input_ids = input_ids.to(f"cuda:{t5_device}")
73
+
74
+ # Generasi ringkasan T5
75
+ summary_ids = t5_model.generate(
76
+ input_ids,
77
+ min_length=int(min_length_val),
78
+ max_length=int(max_length_val),
79
+ num_beams=4, # Jumlah beam untuk beam search (meningkatkan kualitas)
80
+ early_stopping=True # Hentikan generasi lebih awal jika semua beam selesai
81
+ )
82
+ summarized_text = t5_tokenizer.decode(summary_ids[0], skip_special_tokens=True)
83
+ status_message = f"✅ Ringkasan dengan {current_model_name} berhasil!"
84
+
85
+ elif model_choice == "gaduhhartawan/indobart-base-v2":
86
+ current_model_name = "IndoBART v2 (gaduhhartawan/indobart)"
87
+ if indobart_summarizer_pipeline is None:
88
+ status_message = f"❌ Error: {current_model_name} gagal dimuat."
89
+ else:
90
+ # Menggunakan pipeline untuk IndoBART
91
+ summary = indobart_summarizer_pipeline(
92
+ text_input,
93
+ min_length=int(min_length_val),
94
+ max_length=int(max_length_val),
95
+ truncation=True # Tetap penting untuk input panjang
96
+ )
97
+ summarized_text = summary[0]['summary_text']
98
+ status_message = f"✅ Ringkasan dengan {current_model_name} berhasil!"
99
+
100
+ else:
101
+ status_message = "⚠️ Pilihan model tidak valid."
102
+
103
+ # --- Evaluasi Ringkasan (jika ada ringkasan referensi) ---
104
+ eval_table_html = ""
105
+ if summarized_text and reference_summary.strip():
106
+ # Untuk ROUGE, kita perlu list of strings untuk predictions dan references
107
+ predictions = [summarized_text]
108
+ references = [reference_summary] # Asumsikan satu referensi
109
+
110
+ # Hitung skor ROUGE
111
+ rouge_scores = rouge_metric.compute(predictions=predictions, references=references)
112
+
113
+ # Format hasil ke dalam DataFrame untuk tampilan yang lebih baik
114
+ # Mengambil skor F1 untuk ROUGE-1, ROUGE-2, ROUGE-L
115
+ evaluation_data = {
116
+ "Metrik": ["ROUGE-1 F1", "ROUGE-2 F1", "ROUGE-L F1"],
117
+ "Skor": [
118
+ f"{rouge_scores['rouge1']:.4f}",
119
+ f"{rouge_scores['rouge2']:.4f}",
120
+ f"{rouge_scores['rougeL']:.4f}"
121
+ ]
122
+ }
123
+ evaluation_df = pd.DataFrame(evaluation_data)
124
+ eval_table_html = evaluation_df.to_html(index=False)
125
+
126
+ status_message += " Evaluasi ROUGE selesai."
127
+ elif summarized_text:
128
+ status_message += " (Tidak ada ringkasan referensi untuk evaluasi ROUGE)."
129
+
130
+
131
+ result_html = f"""
132
+ <h3>Teks Ringkasan Anda (dengan {current_model_name}):</h3>
133
+ <p>{summarized_text}</p>
134
+ """
135
+
136
+ # Mengembalikan status, HTML hasil, HTML evaluasi, dan teks ringkasan mentah (untuk unduhan)
137
+ return status_message, result_html, eval_table_html, summarized_text
138
+
139
+ except Exception as e:
140
+ return f"❌ Terjadi kesalahan: {str(e)}", "", "", ""
141
+
142
+
143
+ # ---------- GRADIO INTERFACE ----------
144
+ with gr.Blocks(title="Perbandingan Model Ringkasan Bahasa Indonesia") as demo:
145
+ gr.Markdown("# 📝 Perbandingan Model Ringkasan Bahasa Indonesia")
146
+ gr.Markdown("Masukkan teks asli Bahasa Indonesia dan pilih model yang ingin Anda gunakan. Opsional, berikan ringkasan referensi untuk evaluasi ROUGE.")
147
+
148
+ with gr.Row():
149
+ model_choice = gr.Radio(
150
+ choices=["cahya/t5-base-indonesian-summarization-cased", "gaduhhartawan/indobart-base-v2"],
151
+ label="Pilih Model Ringkasan",
152
+ value="cahya/t5-base-indonesian-summarization-cased" # Default pilihan
153
+ )
154
+
155
+ with gr.Row():
156
+ text_input = gr.Textbox(
157
+ label="Teks Asli (Bahasa Indonesia)",
158
+ placeholder="Masukkan teks panjang berbahasa Indonesia yang ingin Anda ringkas di sini...",
159
+ lines=10
160
+ )
161
+
162
+ with gr.Row():
163
+ min_length_slider = gr.Slider(
164
+ minimum=10,
165
+ maximum=100,
166
+ value=30,
167
+ step=1,
168
+ label="Panjang Ringkasan Minimum"
169
+ )
170
+ max_length_slider = gr.Slider(
171
+ minimum=50,
172
+ maximum=200,
173
+ value=80,
174
+ step=1,
175
+ label="Panjang Ringkasan Maksimum"
176
+ )
177
+
178
+ reference_summary_input = gr.Textbox(
179
+ label="Ringkasan Referensi (Opsional untuk Evaluasi ROUGE)",
180
+ placeholder="Masukkan ringkasan yang dibuat manusia untuk teks ini (untuk perbandingan)",
181
+ lines=3
182
+ )
183
+
184
+ summarize_btn = gr.Button("✨ Ringkas & Evaluasi Sekarang")
185
+
186
+ status_output = gr.Markdown(label="Status Proses")
187
+ summary_output = gr.HTML(label="Hasil Ringkasan")
188
+ evaluation_output = gr.HTML(label="Hasil Evaluasi ROUGE")
189
+
190
+ download_btn = gr.File(label="Unduh Ringkasan", visible=False)
191
+
192
+ # Fungsi pembantu untuk tombol unduh
193
+ def update_download_button(summarized_text_content):
194
+ if summarized_text_content:
195
+ # Menggunakan io.BytesIO untuk membuat file di memori
196
+ # Encode ke utf-8 karena teks mungkin mengandung karakter non-ASCII
197
+ file_data = summarized_text_content.encode('utf-8')
198
+ return gr.File(value=file_data,
199
+ file_name="ringkasan_hasil.txt",
200
+ visible=True)
201
+ return gr.File(visible=False)
202
+
203
+ # Menghubungkan tombol ke fungsi ringkasan dan evaluasi
204
+ summarize_btn.click(
205
+ fn=summarize_and_evaluate,
206
+ inputs=[text_input, model_choice, min_length_slider, max_length_slider, reference_summary_input],
207
+ # Perhatikan outputs: summarized_text (ke-4) akan masuk ke input ke-4 dari lambda di .success
208
+ outputs=[status_output, summary_output, evaluation_output, gr.State()]
209
+ # gr.State() digunakan sebagai placeholder untuk summarized_text mentah yang akan diteruskan ke .success
210
+ ).success(
211
+ # Lambda ini menerima 4 argumen: status, html_ringkasan, html_evaluasi, dan teks_ringkasan_mentah
212
+ fn=lambda s_out, h_out, e_out, text_raw: update_download_button(text_raw),
213
+ inputs=[status_output, summary_output, evaluation_output, gr.State()], # Input untuk lambda, mengambil output dari summarize_and_evaluate
214
+ outputs=download_btn
215
+ )
216
+
217
+
218
+ gr.Markdown("""
219
+ ---
220
+ <div style='text-align: center; margin-top: 20px;'>
221
+ <p>Didukung oleh Hugging Face Transformers dan Gradio.</p>
222
+ <p>Model: <a href="https://huggingface.co/cahya/t5-base-indonesian-summarization-cased" target="_blank">cahya/t5-base-indonesian-summarization-cased</a> dan <a href="https://huggingface.co/gaduhhartawan/indobart-base-v2" target="_blank">gaduhhartawan/indobart-base-v2</a></p>
223
+ </div>
224
+ """)
225
+
226
+ #Run
227
+ if __name__ == "__main__":
228
+ demo.launch()