Spaces:
Sleeping
Sleeping
Update app.py
Browse files
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 |
-
|
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 |
-
-
|
46 |
-
-
|
47 |
-
-
|
48 |
-
- Sử dụng TextIteratorStreamer để stream phản hồi từ mô hình
|
49 |
"""
|
50 |
-
#
|
51 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
|
|
|
53 |
# Chọn top 7 cột phù hợp
|
54 |
-
k =
|
55 |
-
column_similarities = util.cos_sim(
|
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(
|
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
|
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
|
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
|
75 |
-
Dưới đây là dữ liệu bạn cần phân tích và tổng hợp
|
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 |
-
|
96 |
-
|
97 |
-
|
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 |
-
|
103 |
|
104 |
-
#
|
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
|
130 |
-
- Thêm tin nhắn của người dùng vào
|
131 |
-
-
|
|
|
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 messages và dù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)
|