beyoru commited on
Commit
74d34f4
·
verified ·
1 Parent(s): 12f9bba

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +51 -34
app.py CHANGED
@@ -31,48 +31,59 @@ row_texts = df.apply(lambda row: " | ".join(row.astype(str)), axis=1)
31
  row_embeddings = embedding_model.encode(row_texts.tolist(), convert_to_tensor=True)
32
 
33
  # Load mô hình Qwen và tokenizer cho việc tạo phản hồi
34
- fc_model = AutoModelForCausalLM.from_pretrained('Qwen/Qwen2.5-3B-Instruct', torch_dtype=torch.float16)\
35
- #.to("cuda")
36
  fc_tokenizer = AutoTokenizer.from_pretrained('Qwen/Qwen2.5-3B-Instruct')
37
 
38
  # --------------------------
39
  # Hàm tạo phản hồi streaming theo thời gian thực
40
  # --------------------------
41
-
42
- def generate_response(user_query: str):
43
  """
44
  Hàm này sẽ:
45
- - Tính embedding cho câu truy vấn của người dùng.
46
- - Chọn ra top 3 cột và top 10 dòng phù hợp từ dữ liệu.
47
- - Tạo system prompt bao gồm bảng dữ liệu đã được format bằng tabulate.
48
- - Sử dụng TextIteratorStreamer để stream phản hồi từ mô hình theo thời gian thực.
49
  """
50
- # Tính embedding cho câu truy vấn
51
- question_embedding = embedding_model.encode(user_query, convert_to_tensor=True)
 
 
 
 
 
 
 
 
 
 
 
52
 
 
53
  # Chọn top 7 cột phù hợp
54
- k = 7
55
- column_similarities = util.cos_sim(question_embedding, column_embeddings)[0]
56
  best_column_indices = torch.topk(column_similarities, k).indices.tolist()
57
  best_column_names = [column_names[i] for i in best_column_indices]
58
 
59
  # Chọn top 10 dòng phù hợp
60
- row_similarities = util.cos_sim(question_embedding, row_embeddings).squeeze(0)
61
  m = 10
62
  best_row_indices = torch.topk(row_similarities, m).indices.tolist()
63
  filtered_df = df.iloc[best_row_indices][best_column_names]
64
 
65
- # Format bảng dữ liệu sử dụng tabulate
66
  from tabulate import tabulate
67
  table_text = tabulate(filtered_df, headers=best_column_names, tablefmt="grid")
68
 
69
- # Tạo system prompt chứa thông tin bảng dữ liệu (feat GPT-4)
70
  system_prompt = f"""\
71
  **Notes: Always respond in Vietnamese**
72
- Bạn là một trợ lý báo cáo sản xuất thông minh.
73
 
74
- **Chỉ báo cáo về bảng dưới đây nếu người dùng yêu cầu, nếu không thì cứ giao tiếp bình thường.**
75
- Dưới đây là dữ liệu bạn cần phân tích và tổng hợp dữ liệu một cách rõ ràng, dễ hiểu:
76
  🔹 Các cột dữ liệu liên quan: {', '.join(best_column_names)}
77
  🔹 Bảng dữ liệu:
78
  {table_text}
@@ -92,16 +103,23 @@ Nếu có thể, đề xuất giải pháp hoặc hành động tiếp theo.
92
  🚀 "Nếu duy trì tốc độ này, sản lượng tháng có thể vượt kế hoạch 10%."
93
  🚀 "Không có gì, nếu bạn cần thêm thông tin chi tiết hãy nói cho tôi biết nhé."
94
  """
95
- messages = [
96
- {'role': 'system', 'content': system_prompt},
97
- {'role': 'user', 'content': user_query}
98
- ]
 
 
 
 
 
 
 
99
 
100
  response_template = fc_tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
101
- response_inputs = fc_tokenizer(response_template, return_tensors="pt")\
102
- #.to("cuda")
103
 
104
- # Dùng TextIteratorStreamer để stream phản hồi
105
  streamer = TextIteratorStreamer(fc_tokenizer, skip_prompt=True, skip_special_tokens=True)
106
 
107
  thread = threading.Thread(
@@ -120,22 +138,21 @@ Nếu có thể, đề xuất giải pháp hoặc hành động tiếp theo.
120
  collected_text += new_text
121
  yield collected_text
122
 
123
- # --------------------------
124
- # Hàm giao diện chat
125
- # --------------------------
126
-
127
  def chat_interface(user_message, history):
128
  """
129
- Hàm này sẽ:
130
- - Thêm tin nhắn của người dùng vào lịch sử chat (dưới dạng cặp [tin nhắn người dùng, phản hồi AI]).
131
- - Stream phản hồi từ hình theo thời gian thựccập nhật lịch sử.
 
132
  """
133
  history.append([user_message, ""])
134
  yield "", history
135
- for partial_response in generate_response(user_message):
136
  history[-1][1] = partial_response
137
  yield "", history
138
 
 
 
139
  # --------------------------
140
  # Xây dựng giao diện Gradio với 2 tab: Chat và Production Data Sample
141
  # --------------------------
@@ -154,4 +171,4 @@ with gr.Blocks() as demo:
154
  with gr.TabItem("Production Data Sample"):
155
  # gr.Markdown("Dưới đây là bảng **production_data** mẫu:")
156
  production_table = gr.Dataframe(value=production_data_df, label="Production Data Sample")
157
- demo.launch()
 
31
  row_embeddings = embedding_model.encode(row_texts.tolist(), convert_to_tensor=True)
32
 
33
  # Load mô hình Qwen và tokenizer cho việc tạo phản hồi
34
+ fc_model = AutoModelForCausalLM.from_pretrained('Qwen/Qwen2.5-3B-Instruct', torch_dtype=torch.float16)
35
+ #.to("cuda")
36
  fc_tokenizer = AutoTokenizer.from_pretrained('Qwen/Qwen2.5-3B-Instruct')
37
 
38
  # --------------------------
39
  # Hàm tạo phản hồi streaming theo thời gian thực
40
  # --------------------------
41
+ def generate_response(user_query: str, history):
 
42
  """
43
  Hàm này sẽ:
44
+ - Sử dụng 2 cuộc đối thoại gần nhất từ history để tính embedding.
45
+ - Dựa trên embedding này, chọn ra top 7 cột và top 10 dòng phù hợp.
46
+ - Nạp lịch sử (ví dụ 10 lượt đối thoại gần nhất) vào messages để mô hình có "ký ức".
47
+ - Sử dụng TextIteratorStreamer để stream phản hồi từ mô hình.
48
  """
49
+ # --- Phần tính embedding chỉ dùng 2 cuộc đối thoại gần nhất ---
50
+ num_exchanges_for_embedding = 1
51
+ embedding_history = history[-num_exchanges_for_embedding:] if len(history) >= num_exchanges_for_embedding else history
52
+
53
+ # Ghép các lượt đối thoại (chỉ những lượt đã có phản hồi) thành chuỗi context
54
+ conversation_context = " ".join(
55
+ [f"User: {turn[0]} Assistant: {turn[1]}" for turn in embedding_history if turn[1]]
56
+ )
57
+ if conversation_context.strip() == "":
58
+ conversation_context = user_query
59
+
60
+ # Tính embedding cho context
61
+ context_embedding = embedding_model.encode(conversation_context, convert_to_tensor=True)
62
 
63
+ # --- Chọn dữ liệu từ DataFrame dựa trên embedding ---
64
  # Chọn top 7 cột phù hợp
65
+ k = 10
66
+ column_similarities = util.cos_sim(context_embedding, column_embeddings)[0]
67
  best_column_indices = torch.topk(column_similarities, k).indices.tolist()
68
  best_column_names = [column_names[i] for i in best_column_indices]
69
 
70
  # Chọn top 10 dòng phù hợp
71
+ row_similarities = util.cos_sim(context_embedding, row_embeddings).squeeze(0)
72
  m = 10
73
  best_row_indices = torch.topk(row_similarities, m).indices.tolist()
74
  filtered_df = df.iloc[best_row_indices][best_column_names]
75
 
76
+ # Format bảng dữ liệu dùng tabulate
77
  from tabulate import tabulate
78
  table_text = tabulate(filtered_df, headers=best_column_names, tablefmt="grid")
79
 
80
+ # --- Tạo system prompt chứa thông tin bảng dữ liệu ---
81
  system_prompt = f"""\
82
  **Notes: Always respond in Vietnamese**
83
+ Bạn là một trợ lý báo cáo sản xuất thông minh đồng thời là một người bạn thân thiện.
84
 
85
+ **Chỉ báo cáo về bảng dưới đây nếu người dùng yêu cầu, nếu không thì cứ giao tiếp tự nhiên và đừng đề cập gì đến bảng.**
86
+ Dưới đây là dữ liệu bạn cần phân tích và tổng hợp:
87
  🔹 Các cột dữ liệu liên quan: {', '.join(best_column_names)}
88
  🔹 Bảng dữ liệu:
89
  {table_text}
 
103
  🚀 "Nếu duy trì tốc độ này, sản lượng tháng có thể vượt kế hoạch 10%."
104
  🚀 "Không có gì, nếu bạn cần thêm thông tin chi tiết hãy nói cho tôi biết nhé."
105
  """
106
+ print(table_text)
107
+ # --- Nạp lịch sử đối thoại vào messages để mô hình có "ký ức" ---
108
+ num_exchanges_for_messages = 10
109
+ messages_history = history[-num_exchanges_for_messages:] if len(history) > num_exchanges_for_messages else history
110
+
111
+ messages = [{'role': 'system', 'content': system_prompt}]
112
+ for turn in messages_history[:-1]:
113
+ messages.append({'role': 'user', 'content': turn[0]})
114
+ messages.append({'role': 'assistant', 'content': turn[1]})
115
+ # Thêm lượt hiện tại (chỉ tin nhắn của user, chưa có phản hồi)
116
+ messages.append({'role': 'user', 'content': messages_history[-1][0]})
117
 
118
  response_template = fc_tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
119
+ response_inputs = fc_tokenizer(response_template, return_tensors="pt")
120
+ #.to("cuda")
121
 
122
+ # --- Stream phản hồi từ mô hình ---
123
  streamer = TextIteratorStreamer(fc_tokenizer, skip_prompt=True, skip_special_tokens=True)
124
 
125
  thread = threading.Thread(
 
138
  collected_text += new_text
139
  yield collected_text
140
 
 
 
 
 
141
  def chat_interface(user_message, history):
142
  """
143
+ Hàm này:
144
+ - Thêm tin nhắn mới của người dùng vào history.
145
+ - Gọi generate_response với history (nạp cả lịch sử vào messagesdùng 2 lượt đối thoại gần nhất cho embedding).
146
+ - Stream phản hồi từ mô hình và cập nhật history.
147
  """
148
  history.append([user_message, ""])
149
  yield "", history
150
+ for partial_response in generate_response(user_message, history):
151
  history[-1][1] = partial_response
152
  yield "", history
153
 
154
+
155
+
156
  # --------------------------
157
  # Xây dựng giao diện Gradio với 2 tab: Chat và Production Data Sample
158
  # --------------------------
 
171
  with gr.TabItem("Production Data Sample"):
172
  # gr.Markdown("Dưới đây là bảng **production_data** mẫu:")
173
  production_table = gr.Dataframe(value=production_data_df, label="Production Data Sample")
174
+ demo.launch(debug=True)