xuandin commited on
Commit
8a052ba
·
verified ·
1 Parent(s): 35de67c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +168 -82
app.py CHANGED
@@ -5,6 +5,7 @@ from semviqa.ser.qatc_model import QATCForQuestionAnswering
5
  from semviqa.tvc.model import ClaimModelForClassification
6
  from semviqa.ser.ser_eval import extract_evidence_tfidf_qatc
7
  from semviqa.tvc.tvc_eval import classify_claim
 
8
 
9
  # Load models with caching
10
  @st.cache_resource()
@@ -14,19 +15,26 @@ def load_model(model_name, model_class, is_bc=False):
14
  model.eval()
15
  return tokenizer, model
16
 
17
- # Page Configuration
18
  st.set_page_config(page_title="SemViQA Demo", layout="wide")
19
 
20
- # Custom CSS for improved UI
21
  st.markdown("""
22
  <style>
23
- body {
24
- font-family: 'Arial', sans-serif;
 
 
 
 
 
 
 
25
  }
26
  .big-title {
27
  font-size: 36px;
28
  font-weight: bold;
29
- color: #0078D4;
30
  text-align: center;
31
  margin-top: 20px;
32
  }
@@ -43,10 +51,10 @@ st.markdown("""
43
  width: 100%;
44
  border-radius: 8px;
45
  padding: 10px;
46
- transition: 0.3s;
47
  }
48
- .stButton>button:hover {
49
- background-color: #45a049;
 
50
  }
51
  .result-box {
52
  background-color: #f9f9f9;
@@ -58,6 +66,7 @@ st.markdown("""
58
  .verdict {
59
  font-size: 24px;
60
  font-weight: bold;
 
61
  display: flex;
62
  align-items: center;
63
  }
@@ -67,87 +76,164 @@ st.markdown("""
67
  </style>
68
  """, unsafe_allow_html=True)
69
 
70
- # Page Header
71
- st.markdown("<p class='big-title'>SemViQA: Vietnamese Fact-Checking System</p>", unsafe_allow_html=True)
72
- st.markdown("<p class='sub-title'>Enter a claim and context to verify its accuracy</p>", unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
 
74
- # Sidebar: Settings
75
- with st.sidebar.expander("⚙️ Settings", expanded=True):
76
- tfidf_threshold = st.slider("TF-IDF Threshold", 0.0, 1.0, 0.5, 0.01)
77
- length_ratio_threshold = st.slider("Length Ratio Threshold", 0.1, 1.0, 0.5, 0.01)
78
- qatc_model_name = st.selectbox("QATC Model", [
79
- "SemViQA/qatc-infoxlm-viwikifc",
80
- "SemViQA/qatc-infoxlm-isedsc01",
81
- "SemViQA/qatc-vimrc-viwikifc",
82
- "SemViQA/qatc-vimrc-isedsc01"
83
- ])
84
- bc_model_name = st.selectbox("Binary Classification Model", [
85
- "SemViQA/bc-xlmr-viwikifc",
86
- "SemViQA/bc-xlmr-isedsc01",
87
- "SemViQA/bc-infoxlm-viwikifc",
88
- "SemViQA/bc-infoxlm-isedsc01",
89
- "SemViQA/bc-erniem-viwikifc",
90
- "SemViQA/bc-erniem-isedsc01"
91
- ])
92
- tc_model_name = st.selectbox("Three-Class Classification Model", [
93
- "SemViQA/tc-xlmr-viwikifc",
94
- "SemViQA/tc-xlmr-isedsc01",
95
- "SemViQA/tc-infoxlm-viwikifc",
96
- "SemViQA/tc-infoxlm-isedsc01",
97
- "SemViQA/tc-erniem-viwikifc",
98
- "SemViQA/tc-erniem-isedsc01"
99
- ])
100
- show_details = st.checkbox("Show probability details", value=False)
101
 
102
- # Load Models
103
- tokenizer_qatc, model_qatc = load_model(qatc_model_name, QATCForQuestionAnswering)
104
- tokenizer_bc, model_bc = load_model(bc_model_name, ClaimModelForClassification, is_bc=True)
105
- tokenizer_tc, model_tc = load_model(tc_model_name, ClaimModelForClassification)
106
 
107
- # Define verdict icons
108
- verdict_icons = {
109
- "SUPPORTED": "✅",
110
- "REFUTED": "❌",
111
- "NEI": "⚠️"
112
- }
113
 
114
- # Tabs for functionalities
115
- tabs = st.tabs(["Verify", "History", "About"])
116
 
117
- # --- Verify Tab ---
118
- with tabs[0]:
119
- st.subheader("Verify a Claim")
120
- claim = st.text_area("Enter Claim", "Vietnam is a country in Southeast Asia.")
121
- context = st.text_area("Enter Context", "Vietnam is a country located in Southeast Asia.")
122
-
123
- if st.button("Verify", key="verify_button"):
124
- with st.spinner("Verifying..."):
125
- with torch.no_grad():
126
- evidence = extract_evidence_tfidf_qatc(
127
- claim, context, model_qatc, tokenizer_qatc,
128
- "cuda" if torch.cuda.is_available() else "cpu",
129
- confidence_threshold=tfidf_threshold,
130
- length_ratio_threshold=length_ratio_threshold
131
- )
132
- verdict = "NEI"
133
- prob3class, pred_tc = classify_claim(claim, evidence, model_tc, tokenizer_tc, "cuda" if torch.cuda.is_available() else "cpu")
134
- if pred_tc != 0:
135
- prob2class, pred_bc = classify_claim(claim, evidence, model_bc, tokenizer_bc, "cuda" if torch.cuda.is_available() else "cpu")
136
- verdict = "SUPPORTED" if pred_bc == 0 else "REFUTED" if prob2class > prob3class else ["NEI", "SUPPORTED", "REFUTED"][pred_tc]
137
-
138
- # Display result
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  st.markdown(f"""
140
  <div class='result-box'>
141
- <h3>Result</h3>
142
- <p><strong>Evidence:</strong> {evidence}</p>
143
- <p class='verdict'><span class='verdict-icon'>{verdict_icons.get(verdict, '')}</span>{verdict}</p>
 
144
  </div>
145
  """, unsafe_allow_html=True)
146
-
147
- if torch.cuda.is_available():
148
- torch.cuda.empty_cache()
 
 
 
 
 
 
 
 
 
 
 
149
 
150
- # --- About Tab ---
151
- with tabs[2]:
152
- st.subheader("About SemViQA")
153
- st.markdown("""SemViQA is a semantic fact-checking system for Vietnamese information verification.""")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  from semviqa.tvc.model import ClaimModelForClassification
6
  from semviqa.ser.ser_eval import extract_evidence_tfidf_qatc
7
  from semviqa.tvc.tvc_eval import classify_claim
8
+ import io
9
 
10
  # Load models with caching
11
  @st.cache_resource()
 
15
  model.eval()
16
  return tokenizer, model
17
 
18
+ # Set up page configuration
19
  st.set_page_config(page_title="SemViQA Demo", layout="wide")
20
 
21
+ # Custom CSS: giới hạn chiều cao, bố cục hai cột, và định dạng ô Result
22
  st.markdown("""
23
  <style>
24
+ html, body {
25
+ height: 100%;
26
+ margin: 0;
27
+ overflow: hidden;
28
+ }
29
+ .main-container {
30
+ height: 100vh;
31
+ overflow-y: auto;
32
+ padding: 20px;
33
  }
34
  .big-title {
35
  font-size: 36px;
36
  font-weight: bold;
37
+ color: #4A90E2;
38
  text-align: center;
39
  margin-top: 20px;
40
  }
 
51
  width: 100%;
52
  border-radius: 8px;
53
  padding: 10px;
 
54
  }
55
+ .stTextArea textarea {
56
+ font-size: 16px;
57
+ min-height: 120px;
58
  }
59
  .result-box {
60
  background-color: #f9f9f9;
 
66
  .verdict {
67
  font-size: 24px;
68
  font-weight: bold;
69
+ margin: 0;
70
  display: flex;
71
  align-items: center;
72
  }
 
76
  </style>
77
  """, unsafe_allow_html=True)
78
 
79
+ # Đóng gói toàn bộ nội dung trong 1 container có chiều cao cố định
80
+ with st.container():
81
+ st.markdown("<p class='big-title'>SemViQA: Hệ thống Kiểm chứng Thông tin bằng Semantic QA cho Tiếng Việt</p>", unsafe_allow_html=True)
82
+ st.markdown("<p class='sub-title'>Nhập thông tin cần kiểm chứng và ngữ cảnh để xác minh độ chính xác</p>", unsafe_allow_html=True)
83
+
84
+ # Sidebar: Global Settings
85
+ with st.sidebar.expander("⚙️ Cài đặt", expanded=True):
86
+ tfidf_threshold = st.slider("Ngưỡng TF-IDF", 0.0, 1.0, 0.5, 0.01)
87
+ length_ratio_threshold = st.slider("Ngưỡng Tỉ lệ độ dài", 0.1, 1.0, 0.5, 0.01)
88
+ qatc_model_name = st.selectbox("Mô hình QATC", [
89
+ "SemViQA/qatc-infoxlm-viwikifc",
90
+ "SemViQA/qatc-infoxlm-isedsc01",
91
+ "SemViQA/qatc-vimrc-viwikifc",
92
+ "SemViQA/qatc-vimrc-isedsc01"
93
+ ])
94
+ bc_model_name = st.selectbox("Mô hình Phân loại Nhị phân", [
95
+ "SemViQA/bc-xlmr-viwikifc",
96
+ "SemViQA/bc-xlmr-isedsc01",
97
+ "SemViQA/bc-infoxlm-viwikifc",
98
+ "SemViQA/bc-infoxlm-isedsc01",
99
+ "SemViQA/bc-erniem-viwikifc",
100
+ "SemViQA/bc-erniem-isedsc01"
101
+ ])
102
+ tc_model_name = st.selectbox("Mô hình Phân loại 3 lớp", [
103
+ "SemViQA/tc-xlmr-viwikifc",
104
+ "SemViQA/tc-xlmr-isedsc01",
105
+ "SemViQA/tc-infoxlm-viwikifc",
106
+ "SemViQA/tc-infoxlm-isedsc01",
107
+ "SemViQA/tc-erniem-viwikifc",
108
+ "SemViQA/tc-erniem-isedsc01"
109
+ ])
110
+ show_details = st.checkbox("Hiển thị chi tiết xác suất", value=False)
111
 
112
+ # Lưu lịch sử kiểm chứng
113
+ if 'history' not in st.session_state:
114
+ st.session_state.history = []
115
+ if 'latest_result' not in st.session_state:
116
+ st.session_state.latest_result = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
 
118
+ # Load các mô hình đã chọn
119
+ tokenizer_qatc, model_qatc = load_model(qatc_model_name, QATCForQuestionAnswering)
120
+ tokenizer_bc, model_bc = load_model(bc_model_name, ClaimModelForClassification, is_bc=True)
121
+ tokenizer_tc, model_tc = load_model(tc_model_name, ClaimModelForClassification)
122
 
123
+ # Icon cho kết quả
124
+ verdict_icons = {
125
+ "SUPPORTED": "✅",
126
+ "REFUTED": "❌",
127
+ "NEI": "⚠️"
128
+ }
129
 
130
+ # Tạo các tab: Verify, History, About
131
+ tabs = st.tabs(["Verify", "History", "About"])
132
 
133
+ # --- Tab Verify ---
134
+ with tabs[0]:
135
+ st.subheader("Kiểm chứng một thông tin")
136
+ # Sử dụng layout 2 cột: bên trái là input, bên phải ô hiển thị kết quả
137
+ col_input, col_result = st.columns([2, 1])
138
+
139
+ with col_input:
140
+ claim = st.text_area("Nhập Claim", "Vietnam is a country in Southeast Asia.")
141
+ context = st.text_area("Nhập Context", "Vietnam is a country located in Southeast Asia, covering an area of over 331,000 km² with a population of more than 98 million people.")
142
+ if st.button("Kiểm chứng", key="verify_button"):
143
+ with st.spinner("Đang kiểm chứng..."):
144
+ with torch.no_grad():
145
+ # Trích xuất bằng chứng và phân loại thông tin
146
+ evidence = extract_evidence_tfidf_qatc(
147
+ claim, context, model_qatc, tokenizer_qatc,
148
+ "cuda" if torch.cuda.is_available() else "cpu",
149
+ confidence_threshold=tfidf_threshold,
150
+ length_ratio_threshold=length_ratio_threshold
151
+ )
152
+ verdict = "NEI"
153
+ details = ""
154
+ prob3class, pred_tc = classify_claim(
155
+ claim, evidence, model_tc, tokenizer_tc,
156
+ "cuda" if torch.cuda.is_available() else "cpu"
157
+ )
158
+ if pred_tc != 0:
159
+ prob2class, pred_bc = classify_claim(
160
+ claim, evidence, model_bc, tokenizer_bc,
161
+ "cuda" if torch.cuda.is_available() else "cpu"
162
+ )
163
+ if pred_bc == 0:
164
+ verdict = "SUPPORTED"
165
+ elif prob2class > prob3class:
166
+ verdict = "REFUTED"
167
+ else:
168
+ verdict = ["NEI", "SUPPORTED", "REFUTED"][pred_tc]
169
+ if show_details:
170
+ details = f"<p><strong>3-Class Probability:</strong> {prob3class.item():.2f} - <strong>2-Class Probability:</strong> {prob2class.item():.2f}</p>"
171
+
172
+ # Lưu lịch sử kiểm chứng và kết quả mới nhất
173
+ st.session_state.history.append({
174
+ "claim": claim,
175
+ "evidence": evidence,
176
+ "verdict": verdict
177
+ })
178
+ st.session_state.latest_result = {
179
+ "claim": claim,
180
+ "evidence": evidence,
181
+ "verdict": verdict,
182
+ "details": details
183
+ }
184
+
185
+ if torch.cuda.is_available():
186
+ torch.cuda.empty_cache()
187
+
188
+ # Hiển thị kết quả ở cột bên phải
189
+ with col_result:
190
+ st.markdown("<h3>Kết quả kiểm chứng</h3>", unsafe_allow_html=True)
191
+ if st.session_state.latest_result is not None:
192
+ res = st.session_state.latest_result
193
  st.markdown(f"""
194
  <div class='result-box'>
195
+ <p><strong>Claim:</strong> {res['claim']}</p>
196
+ <p><strong>Bằng chứng:</strong> {res['evidence']}</p>
197
+ <p class='verdict'><span class='verdict-icon'>{verdict_icons.get(res['verdict'], '')}</span>{res['verdict']}</p>
198
+ {res['details']}
199
  </div>
200
  """, unsafe_allow_html=True)
201
+ # Tính năng tải xuống kết quả kiểm chứng
202
+ result_text = f"Claim: {res['claim']}\nEvidence: {res['evidence']}\nVerdict: {res['verdict']}\nDetails: {res['details']}"
203
+ st.download_button("Tải xuống kết quả", data=result_text, file_name="ketqua_kiemchung.txt", mime="text/plain")
204
+ else:
205
+ st.info("Chưa có kết quả kiểm chứng nào.")
206
+
207
+ # --- Tab History ---
208
+ with tabs[1]:
209
+ st.subheader("Lịch sử kiểm chứng")
210
+ if st.session_state.history:
211
+ for idx, record in enumerate(reversed(st.session_state.history), 1):
212
+ st.markdown(f"**{idx}. Claim:** {record['claim']} \n**Kết quả:** {verdict_icons.get(record['verdict'], '')} {record['verdict']}")
213
+ else:
214
+ st.write("Chưa có lịch sử kiểm chứng nào.")
215
 
216
+ # --- Tab About ---
217
+ with tabs[2]:
218
+ st.subheader("Giới thiệu")
219
+ st.markdown("""
220
+ <p align="center">
221
+ <a href="https://arxiv.org/abs/2503.00955">
222
+ <img src="https://img.shields.io/badge/arXiv-2411.00918-red?style=flat&label=arXiv">
223
+ </a>
224
+ <a href="https://huggingface.co/SemViQA">
225
+ <img src="https://img.shields.io/badge/Hugging%20Face-Model-yellow?style=flat">
226
+ </a>
227
+ <a href="https://pypi.org/project/SemViQA">
228
+ <img src="https://img.shields.io/pypi/v/SemViQA?color=blue&label=PyPI">
229
+ </a>
230
+ <a href="https://github.com/DAVID-NGUYEN-S16/SemViQA">
231
+ <img src="https://img.shields.io/github/stars/DAVID-NGUYEN-S16/SemViQA?style=social">
232
+ </a>
233
+ </p>
234
+ """, unsafe_allow_html=True)
235
+ st.markdown("""
236
+ **Mô tả:**
237
+ SemViQA là hệ thống Semantic QA được thiết kế để kiểm chứng thông tin trong tiếng Việt.
238
+ Hệ thống trích xuất bằng chứng từ ngữ cảnh được cung cấp và phân loại thông tin là **SUPPORTED**, **REFUTED**, hoặc **NEI** (Not Enough Information) dựa trên các mô hình tiên tiến.
239
+ """)