baobuiquang commited on
Commit
00c9a21
1 Parent(s): b83df1c

initial commit

Browse files
Files changed (5) hide show
  1. .gitignore +2 -0
  2. README.md +181 -13
  3. app.py +74 -55
  4. data/sample.xlsx +0 -0
  5. requirements.txt +0 -0
.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ venv/
2
+ .vscode/
README.md CHANGED
@@ -1,13 +1,181 @@
1
- ---
2
- title: Chatbot
3
- emoji: 🐠
4
- colorFrom: green
5
- colorTo: indigo
6
- sdk: gradio
7
- sdk_version: 4.22.0
8
- app_file: app.py
9
- pinned: false
10
- license: unknown
11
- ---
12
-
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Natural Language Q&A Chatbot
2
+
3
+ ## Problem
4
+
5
+ Input:
6
+ * `data` - Example: `data/sample.xlsx`
7
+ * `question` - Example: "Tổng số hồ sơ chứng thực chữ ký vào ngày 12 tháng 1 năm 2024 là bao nhiêu?"
8
+
9
+ Expected output:
10
+ * `answer`: Example: "165"
11
+
12
+ ## Solution Approach
13
+
14
+ ### Preprocessing `data`:
15
+
16
+ * Raw Data (`.XLSX`)
17
+ * ↳ Raw Dataframe (`Pandas DF`)
18
+ * ↳ Preprocessed Dataframe (`Pandas DF`)
19
+
20
+
21
+ ### Feature Extracting `data` and `question`:
22
+
23
+ * Preprocessed Dataframe Data / Question (`String`)
24
+ * ↳ Embedding (`PyTorch Tensor`)
25
+
26
+ #### Model:
27
+ * Stable Model: [HF/XLM-ROBERTA-ME5-BASE](https://huggingface.co/baobuiquang/XLM-ROBERTA-ME5-BASE) (License: [MIT License](https://choosealicense.com/licenses/mit/))
28
+ * Forked from: [HF/multilingual-e5-base](https://huggingface.co/intfloat/multilingual-e5-base) (License: [MIT License](https://choosealicense.com/licenses/mit/))
29
+ * Initialized from [xlm-roberta-base](https://huggingface.co/xlm-roberta-base) (License: [MIT License](https://choosealicense.com/licenses/mit/))
30
+
31
+
32
+ ### Feature Map Down Sampling Method: [Mean Pooling](https://paperswithcode.com/method/average-pooling)
33
+
34
+ * Reduce computationally expensive -> Fast chatbot (Speed)
35
+ * Prevent overfitting -> Better answer (Accuracy)
36
+
37
+ ### Measurement: [Cosine Similarity](https://en.wikipedia.org/wiki/Cosine_similarity)
38
+ * Input:
39
+ * Embedding `a` (`PyTorch Tensor`)
40
+ * Embedding `b` (`PyTorch Tensor`)
41
+ * Output:
42
+ * Cosine Similarity: The cosine of the angle between the 2 non-zero vectors `a` and `b` in space.
43
+ ```
44
+ cos_sim = np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
45
+ ```
46
+
47
+ ### Interactive UI
48
+
49
+ Chatbot's Web UI is currently built with [gradio](https://github.com/gradio-app/gradio) (License: [Apache-2.0 License](https://choosealicense.com/licenses/apache-2.0/)).
50
+
51
+ ## Example and Rough Explanation
52
+
53
+ Sample data: [sample.xlsx](https://github.com/baobuiquang/nlqna-chatbot/blob/main/data/sample.xlsx)
54
+
55
+ ### Step 1. Input:
56
+ * `question` = "Tổng số hồ sơ chứng thực chữ ký vào ngày 12 tháng 1 năm 2024 là bao nhiêu?"
57
+ * `data` = `data/sample.xlsx`
58
+
59
+ | | | | | | |
60
+ | :-----------------------------------------------------: | :---: | :------------: | :------------: | :------------: | :---: |
61
+ | | ... | **11/01/2024** | **12/01/2024** | **13/01/2024** | ... |
62
+ | ... | | | | | |
63
+ | **Tổng số HS chứng thực hợp đồng, giao dịch** | | 156 | 161 | 177 | |
64
+ | **Tổng số HS chứng thực chữ ký** | | 159 | 165 | 182 | |
65
+ | **Tổng số HS chứng thực việc sửa đổi, bổ sung, hủy bỏ** | | 162 | 169 | 187 | |
66
+ | ... | | | | | |
67
+
68
+ ### Step 2. Feature Extraction:
69
+
70
+ * `question` -> `question_embedding` (`PyTorch Tensor`)
71
+ * `data` -> `data_embeddings` (Map of `PyTorch Tensors`)
72
+
73
+ | | | | | | |
74
+ | :-----------------: | :---: | :-----------------: | :-----------------: | :-----------------: | :---: |
75
+ | | ... | ***\<PT Tensor\>*** | ***\<PT Tensor\>*** | ***\<PT Tensor\>*** | ... |
76
+ | ... | | | | | |
77
+ | ***\<PT Tensor\>*** | | 156 | 161 | 177 | |
78
+ | ***\<PT Tensor\>*** | | 159 | 165 | 182 | |
79
+ | ***\<PT Tensor\>*** | | 162 | 169 | 187 | |
80
+ | ... | | | | | |
81
+
82
+ ### Step 3. Measurement Calculation:
83
+
84
+ Calculate the Cosine Similarity between `question_embedding` and `data_embeddings`.
85
+
86
+ | | | | | | |
87
+ | :-------------: | :---: | :-------------: | :-------------: | :-------------: | :---: |
88
+ | | ... | ***{cos_sim}*** | ***{cos_sim}*** | ***{cos_sim}*** | ... |
89
+ | ... | | | | | |
90
+ | ***{cos_sim}*** | | 156 | 161 | 177 | |
91
+ | ***{cos_sim}*** | | 159 | 165 | 182 | |
92
+ | ***{cos_sim}*** | | 162 | 169 | 187 | |
93
+ | ... | | | | | |
94
+
95
+ ### Step 4. Output:
96
+
97
+ Find the highest Cosine Similarity in horizontal and vertical axis to determine the cell for final answer.
98
+
99
+ | | | | | | |
100
+ | :----------------------------: | :---: | :---------: | :----------------------------: | :---------: | :---: |
101
+ | | ... | *{cos_sim}* | ***{highest_cos_sim_x_axis}*** | *{cos_sim}* | ... |
102
+ | ... | | | | | |
103
+ | *{cos_sim}* | | 156 | 161 | 177 | |
104
+ | ***{highest_cos_sim_y_axis}*** | | 159 | ***165*** | 182 | |
105
+ | *{cos_sim}* | | 162 | 169 | 187 | |
106
+ | ... | | | | | |
107
+
108
+ Output the answer (cell value): "165"
109
+
110
+ ## Demo
111
+
112
+ https://github.com/baobuiquang/nlqna-chatbot/assets/60503568/57621579-6a58-4638-9644-b4e482ac975e
113
+
114
+ ## Instructions (Recommended workflow)
115
+
116
+ ### Installation
117
+
118
+ Prerequisites:
119
+ * [Python 3](https://www.python.org/downloads/)
120
+ * [Git](https://git-scm.com/downloads)
121
+
122
+ Clone [this repository](https://github.com/baobuiquang/nlqna-chatbot):
123
+ ```
124
+ git clone https://github.com/baobuiquang/nlqna-chatbot.git
125
+ cd nlqna-chatbot
126
+ ```
127
+
128
+ Create virtual environment:
129
+ ```
130
+ python -m venv venv
131
+ ```
132
+
133
+ Activate virtual environment:
134
+ ```
135
+ venv\Scripts\activate
136
+ ```
137
+
138
+ Upgrade `pip` command:
139
+ ```
140
+ python.exe -m pip install --upgrade pip
141
+ ```
142
+
143
+ Install [required packages/libraries](https://github.com/baobuiquang/nlqna-chatbot/blob/main/requirements.txt):
144
+ ```
145
+ pip install -r requirements.txt
146
+ ```
147
+
148
+ Deactivate virtual environment:
149
+ ```
150
+ deactivate
151
+ ```
152
+
153
+ ### Start chatbot
154
+
155
+ Activate virtual environment:
156
+ ```
157
+ venv\Scripts\activate
158
+ ```
159
+
160
+ Run chatbot app:
161
+ ```
162
+ python app.py
163
+ ```
164
+
165
+ Wait until the terminal print something like this:
166
+ ```
167
+ ...\nlqna-chatbot> python app.py
168
+ Running on local URL: http://127.0.0.1:7860
169
+ To create a public link, set `share=True` in `launch()`.
170
+ ```
171
+
172
+ Now chatbot can be accessed from [http://127.0.0.1:7860](http://127.0.0.1:7860).
173
+
174
+ ### Stop chatbot
175
+
176
+ Press `Ctrl + C` in the terminal to close the chatbot server.
177
+
178
+ Deactivate virtual environment:
179
+ ```
180
+ deactivate
181
+ ```
app.py CHANGED
@@ -1,33 +1,40 @@
1
  # !wget -nc https://raw.githubusercontent.com/baobuiquang/datasets/main/sample.xlsx >& /dev/null
2
  # !pip install gradio==4.21.0 >& /dev/null
3
- import gradio as gr
 
 
 
4
  import pandas as pd
5
  import numpy as np
6
  import torch
 
7
  from transformers import AutoTokenizer, AutoModel
8
- from numpy.linalg import norm
9
  from datetime import datetime
10
- from numpy import dot
11
- pd.options.mode.chained_assignment = None # default='warn'
12
 
13
- FILE_NAME = "sample.xlsx"
 
 
14
  df_map = pd.read_excel(FILE_NAME, header=None, sheet_name=None)
15
  df_map_sheet_names = pd.ExcelFile(FILE_NAME).sheet_names
16
 
 
 
17
  MODEL_NAME = "baobuiquang/XLM-ROBERTA-ME5-BASE"
18
- # MODEL_NAME = "intfloat/multilingual-e5-base" # 10/10
19
- # MODEL_NAME = "keepitreal/vietnamese-sbert" # 9/10
20
- # MODEL_NAME = "sentence-transformers/all-MiniLM-L6-v2" # 9/10
21
- # MODEL_NAME = "BAAI/bge-m3" # 9/10
22
-
23
  tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
24
  model = AutoModel.from_pretrained(MODEL_NAME)
25
 
26
- #Mean Pooling - Take attention mask into account for correct averaging
27
- def mean_pooling(model_output, attention_mask):
28
- token_embeddings = model_output[0] #First element of model_output contains all token embeddings
29
- input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
30
- return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1), min=1e-9)
 
 
 
 
 
 
31
 
32
  # List of Texts -> List of Embeddings
33
  def texts_to_embeddings(list_of_texts):
@@ -38,18 +45,16 @@ def texts_to_embeddings(list_of_texts):
38
  list_of_embeddings = mean_pooling(model_output, encoded_input['attention_mask'])
39
  return list_of_embeddings
40
 
41
- # Text -> Embedding
42
- def text_to_embedding(text):
43
- lower_text = text.lower() # Lowercasing
44
- encoded_input = tokenizer(lower_text, padding=True, truncation=True, return_tensors='pt')
45
- with torch.no_grad():
46
- model_output = model(**encoded_input)
47
- embedding = mean_pooling(model_output, encoded_input['attention_mask'])
48
- return embedding[0]
49
 
50
  # Cosine Similarity between 2 embeddings
51
  def cosine_similarity(a, b):
52
- return dot(a, b)/(norm(a)*norm(b))
53
 
54
  # Find index of the max similarity when comparing an embedding to a list
55
  def similarity(my_embedding, list_of_embeddings):
@@ -64,7 +69,11 @@ def similarity(my_embedding, list_of_embeddings):
64
  max_sim_index = i
65
  return {"max_index": max_sim_index, "max": max_sim, "list": list_of_sim}
66
 
67
- # preprocessed_df_map ==========================================================
 
 
 
 
68
 
69
  preprocessed_df_map = []
70
 
@@ -78,23 +87,29 @@ for sheet_name in df_map_sheet_names:
78
  new_header = []
79
  for e in df.loc[header_position]:
80
  if isinstance(e, datetime):
81
- new_header.append(e.strftime("ngày %-d tháng %-m năm %Y %-d/%-m/%Y %d/%m/%Y"))
 
 
 
 
 
 
82
  else:
83
  new_header.append(e)
84
  df = df.rename(columns = dict(zip(df.columns, new_header)))
85
  df = df.iloc[header_position+1:]
86
 
87
- # Preprocess column "#" values
88
- df['#'] = df['#'].replace(to_replace = r'^\d+(\.\d+)?$', value = np.nan, regex=True)
89
- df['#'] = df['#'].fillna(method = 'ffill')
90
- df = df.dropna(thresh = df.shape[1] * 0.25, axis = 0) # Keep rows that have at least 25% values are not NaN
91
- df = df.dropna(thresh = df.shape[1] * 0.25, axis = 1) # Keep cols that have at least 25% values are not NaN
92
- df = df.rename(columns={'#': 'Nhóm chỉ số'})
93
 
94
- # Move column "#" to the end
95
- columns = list(df.columns)
96
- columns.append(columns.pop(0))
97
- df = df.reindex(columns=columns)
98
 
99
  # General Preprocess
100
  df = df.reset_index(drop=True)
@@ -104,7 +119,11 @@ for sheet_name in df_map_sheet_names:
104
  # Return the preprocessed sheet
105
  preprocessed_df_map.append(df)
106
 
107
- # embeddings_map ===============================================================
 
 
 
 
108
 
109
  x_list_embeddings_map = []
110
  y_list_embeddings_map = []
@@ -113,6 +132,7 @@ for i in range(len(preprocessed_df_map)):
113
 
114
  df = preprocessed_df_map[i]
115
 
 
116
  x_list = list(df['Tên chỉ số'])
117
  y_list = list(df.columns)
118
 
@@ -124,13 +144,8 @@ for i in range(len(preprocessed_df_map)):
124
  x_list_embeddings_map.append(x_list_embeddings)
125
  y_list_embeddings_map.append(y_list_embeddings)
126
 
127
- # ==============================================================================
128
-
129
- # preprocessed_df_map:
130
- # - A list of dataframes (preprocessed), each dataframe contains data from 1 sheet from the XLSX file
131
-
132
- # x/y_list_embeddings_map:
133
- # - A list of pre-calculated embeddings (vectors) of x/y axis in the corresponding dataframe in the `preprocessed_df_map`
134
 
135
  def chatbot_mechanism(message, history, additional_input_1):
136
  # Clarify namings
@@ -153,8 +168,12 @@ def chatbot_mechanism(message, history, additional_input_1):
153
  if x_score < 0.85 or y_score < 0.85:
154
  eval_text = "\n⚠️ Low Cosine Similarity ⚠️"
155
  # Cell value
156
- cell_value = df.loc[x_index][y_index]
157
- return f"**{cell_value}**\n<div style='color: gray; font-size: 80%; font-family: courier, monospace;'>[x={str(round(x_score,2))}, y={str(round(y_score,2))}]{eval_text}</div>"
 
 
 
 
158
 
159
  textbox_input = gr.Textbox(
160
  label = "Câu hỏi",
@@ -211,11 +230,11 @@ with gr.Blocks(
211
  label = 'Câu hỏi ví dụ (Dữ liệu "Tư pháp")',
212
  examples_per_page = 100,
213
  examples = [
214
- "Tổng số hồ sơ chứng thực bản sao từ bản chính tới ngày 10/1/2024 là bao nhiêu?", # 100
215
  "15 tháng 1 năm 2024, hãy tìm dữ liệu tổng số hồ sơ chứng thực hợp đồng, giao dịch.", # 219
216
- "Tổng số hồ sơ chứng thực chữ ký vào ngày 12 tháng 1 năm 2024 là bao nhiêu?", # 165
217
- "Có bao nhiêu HS chứng thực việc sửa đổi, bổ sung, hủy bỏ ngày 14/01/2024?", # 194
218
- "Tính đến ngày 11 tháng 1, 2024, số hồ sơ đăng ký kết hôn là bao nhiêu?", # 177
219
  ],
220
  inputs = [textbox_input],
221
  )
@@ -229,10 +248,10 @@ with gr.Blocks(
229
  examples_per_page = 100,
230
  examples = [
231
  "Số vụ phạm tội công nghệ cao ngày 19 tháng 3 năm 2024 là bao nhiêu?", # 121
232
- "Tới ngày 20/3/2024, có mấy vụ án đặc biệt nghiêm trọng?", # 208
233
- "Ngày 22 tháng 3 năm 2024, có bao nhiêu người chết do TNGT", # 273
234
- "Có bao nhiêu vụ cháy cho đến ngày 24/03/2024?", # 437
235
- "Tìm thông tin số vụ tai nạn giao thông tại ngày 18/3 năm 2024.", # 104
236
  ],
237
  inputs = [textbox_input],
238
  )
@@ -242,4 +261,4 @@ with gr.Blocks(
242
  """
243
  )
244
 
245
- app.launch(debug = False)
 
1
  # !wget -nc https://raw.githubusercontent.com/baobuiquang/datasets/main/sample.xlsx >& /dev/null
2
  # !pip install gradio==4.21.0 >& /dev/null
3
+
4
+ # ==============================
5
+ # ========== PACKAGES ==========
6
+ import gradio as gr # gradio==4.21.0
7
  import pandas as pd
8
  import numpy as np
9
  import torch
10
+ import time
11
  from transformers import AutoTokenizer, AutoModel
 
12
  from datetime import datetime
13
+ # pd.options.mode.chained_assignment = None # default='warn'
 
14
 
15
+ # ===========================
16
+ # ========== FILES ==========
17
+ FILE_NAME = "data/sample.xlsx"
18
  df_map = pd.read_excel(FILE_NAME, header=None, sheet_name=None)
19
  df_map_sheet_names = pd.ExcelFile(FILE_NAME).sheet_names
20
 
21
+ # ============================
22
+ # ========== MODELS ==========
23
  MODEL_NAME = "baobuiquang/XLM-ROBERTA-ME5-BASE"
 
 
 
 
 
24
  tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
25
  model = AutoModel.from_pretrained(MODEL_NAME)
26
 
27
+ # ===============================
28
+ # ========== FUNCTIONS ==========
29
+
30
+ # Text -> Embedding
31
+ def text_to_embedding(text):
32
+ lower_text = text.lower() # Lowercasing
33
+ encoded_input = tokenizer(lower_text, padding=True, truncation=True, return_tensors='pt')
34
+ with torch.no_grad():
35
+ model_output = model(**encoded_input)
36
+ embedding = mean_pooling(model_output, encoded_input['attention_mask'])
37
+ return embedding[0]
38
 
39
  # List of Texts -> List of Embeddings
40
  def texts_to_embeddings(list_of_texts):
 
45
  list_of_embeddings = mean_pooling(model_output, encoded_input['attention_mask'])
46
  return list_of_embeddings
47
 
48
+ # Mean Pooling
49
+ # - Take attention mask into account for correct averaging
50
+ def mean_pooling(model_output, attention_mask):
51
+ token_embeddings = model_output[0] # First element of model_output contains all token embeddings
52
+ input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
53
+ return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1), min=1e-9)
 
 
54
 
55
  # Cosine Similarity between 2 embeddings
56
  def cosine_similarity(a, b):
57
+ return np.dot(a, b)/(np.linalg.norm(a)*np.linalg.norm(b))
58
 
59
  # Find index of the max similarity when comparing an embedding to a list
60
  def similarity(my_embedding, list_of_embeddings):
 
69
  max_sim_index = i
70
  return {"max_index": max_sim_index, "max": max_sim, "list": list_of_sim}
71
 
72
+ # ===================================
73
+ # ========== PREPROCESSING ==========
74
+
75
+ # preprocessed_df_map ----------------------------------------------------------
76
+ # - A list of dataframes (preprocessed), each dataframe contains data from 1 sheet from the XLSX file
77
 
78
  preprocessed_df_map = []
79
 
 
87
  new_header = []
88
  for e in df.loc[header_position]:
89
  if isinstance(e, datetime):
90
+ new_header.append(
91
+ f"\
92
+ ngày {e.strftime('%d').lstrip('0')} tháng {e.strftime('%m').lstrip('0')} năm {e.strftime('%Y')} \
93
+ {e.strftime('%d').lstrip('0')}/{e.strftime('%m').lstrip('0')}/{e.strftime('%Y')} \
94
+ {e.strftime('%d')}/{e.strftime('%m')}/{e.strftime('%Y')} \
95
+ "
96
+ )
97
  else:
98
  new_header.append(e)
99
  df = df.rename(columns = dict(zip(df.columns, new_header)))
100
  df = df.iloc[header_position+1:]
101
 
102
+ # # Preprocess column "#" values
103
+ # df['#'] = df['#'].replace(to_replace = r'^\d+(\.\d+)?$', value = np.nan, regex=True)
104
+ # df['#'] = df['#'].fillna(method = 'ffill')
105
+ # df = df.dropna(thresh = df.shape[1] * 0.25, axis = 0) # Keep rows that have at least 25% values are not NaN
106
+ # df = df.dropna(thresh = df.shape[1] * 0.25, axis = 1) # Keep cols that have at least 25% values are not NaN
107
+ # df = df.rename(columns={'#': 'Nhóm chỉ số'})
108
 
109
+ # # Move column "#" to the end
110
+ # columns = list(df.columns)
111
+ # columns.append(columns.pop(0))
112
+ # df = df.reindex(columns=columns)
113
 
114
  # General Preprocess
115
  df = df.reset_index(drop=True)
 
119
  # Return the preprocessed sheet
120
  preprocessed_df_map.append(df)
121
 
122
+ # ========================================
123
+ # ========== FEATURE EXTRACTION ==========
124
+
125
+ # embeddings_map ---------------------------------------------------------------
126
+ # - A list of pre-calculated embeddings (vectors) of x/y axis in the corresponding dataframe in the `preprocessed_df_map`
127
 
128
  x_list_embeddings_map = []
129
  y_list_embeddings_map = []
 
132
 
133
  df = preprocessed_df_map[i]
134
 
135
+ # HARDCODE
136
  x_list = list(df['Tên chỉ số'])
137
  y_list = list(df.columns)
138
 
 
144
  x_list_embeddings_map.append(x_list_embeddings)
145
  y_list_embeddings_map.append(y_list_embeddings)
146
 
147
+ # ==========================
148
+ # ========== MAIN ==========
 
 
 
 
 
149
 
150
  def chatbot_mechanism(message, history, additional_input_1):
151
  # Clarify namings
 
168
  if x_score < 0.85 or y_score < 0.85:
169
  eval_text = "\n⚠️ Low Cosine Similarity ⚠️"
170
  # Cell value
171
+ cell_value = df.iloc[x_index, y_index]
172
+ final_output_message = f"**{cell_value}**\n<div style='color: gray; font-size: 80%; font-family: courier, monospace;'>[x={str(round(x_score,2))}, y={str(round(y_score,2))}]{eval_text}</div>"
173
+ return final_output_message
174
+ # for i in range(len(final_output_message)):
175
+ # time.sleep(0.1)
176
+ # yield final_output_message[: i+1]
177
 
178
  textbox_input = gr.Textbox(
179
  label = "Câu hỏi",
 
230
  label = 'Câu hỏi ví dụ (Dữ liệu "Tư pháp")',
231
  examples_per_page = 100,
232
  examples = [
233
+ "Tổng số hồ sơ chứng thực bản sao từ bản chính tới ngày 10/1/2024 là bao nhiêu?", # 100
234
  "15 tháng 1 năm 2024, hãy tìm dữ liệu tổng số hồ sơ chứng thực hợp đồng, giao dịch.", # 219
235
+ "Tổng số hồ sơ chứng thực chữ ký vào ngày 12 tháng 1 năm 2024 là bao nhiêu?", # 165
236
+ "Có bao nhiêu HS chứng thực việc sửa đổi, bổ sung, hủy bỏ ngày 14/01/2024?", # 194
237
+ "Tính đến ngày 11 tháng 1, 2024, số hồ sơ đăng ký kết hôn là bao nhiêu?", # 177
238
  ],
239
  inputs = [textbox_input],
240
  )
 
248
  examples_per_page = 100,
249
  examples = [
250
  "Số vụ phạm tội công nghệ cao ngày 19 tháng 3 năm 2024 là bao nhiêu?", # 121
251
+ "Tới ngày 20/3/2024, có mấy vụ án đặc biệt nghiêm trọng?", # 208
252
+ "Ngày 22 tháng 3 năm 2024, có bao nhiêu người chết do TNGT", # 273
253
+ "Có bao nhiêu vụ cháy cho đến ngày 24/03/2024?", # 437
254
+ "Tìm thông tin số vụ tai nạn giao thông tại ngày 18/3 năm 2024.", # 104
255
  ],
256
  inputs = [textbox_input],
257
  )
 
261
  """
262
  )
263
 
264
+ app.launch(debug = False, share = False)
data/sample.xlsx ADDED
Binary file (56.6 kB). View file
 
requirements.txt CHANGED
Binary files a/requirements.txt and b/requirements.txt differ