Spaces:
Sleeping
Sleeping
File size: 9,023 Bytes
dc14176 a4c3bcc dc14176 7f79d8b 985ad3e 80eee0f dc14176 7f79d8b dc14176 7f79d8b dc14176 80eee0f dc14176 7f79d8b 289913c 7f79d8b 289913c 7f79d8b dc14176 7f79d8b 80eee0f 3fc35d8 7f79d8b 289913c 80eee0f 7f79d8b 289913c aab145f 7f79d8b 3fc35d8 7f79d8b 289913c 7f79d8b dc14176 7f79d8b dc14176 7f79d8b dc14176 7f79d8b dc14176 7f79d8b dc14176 7f79d8b dc14176 7f79d8b dc14176 7f79d8b dc14176 80eee0f dc14176 7f79d8b dc14176 7f79d8b 47ed12b 80eee0f 47ed12b dc14176 47ed12b 7f79d8b dc14176 47ed12b dc14176 a4c3bcc dc14176 47ed12b dc14176 47ed12b dc14176 47ed12b dc14176 a4c3bcc |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
import os
import streamlit as st
import torch
from transformers import AutoTokenizer, AutoModel
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
import json
@st.cache_resource
def load_model_and_tokenizer(model_name='intfloat/multilingual-e5-small'):
"""
Cached function to load model and tokenizer
This ensures the model is loaded only once and reused
"""
print("Loading tokenizer...")
tokenizer = AutoTokenizer.from_pretrained(model_name)
print("Loading model...")
model = AutoModel.from_pretrained(model_name, torch_dtype=torch.float16)
return tokenizer, model
class VietnameseChatbot:
def __init__(self, model_name='intfloat/multilingual-e5-small'):
"""
Initialize the Vietnamese chatbot with pre-loaded model and conversation data
"""
# Load pre-trained model and tokenizer using cached function
self.tokenizer, self.model = load_model_and_tokenizer(model_name)
# Load comprehensive conversation dataset
self.conversation_data = self._load_conversation_data()
# Pre-compute embeddings for faster response generation
print("Pre-computing conversation embeddings...")
self.conversation_embeddings = self._compute_embeddings()
def _load_conversation_data(self):
"""
Load a comprehensive conversation dataset
"""
return [
# Greeting conversations
{"query": "Xin chào", "response": "Chào bạn! Tôi có thể giúp gì cho bạn?"},
{"query": "Hi", "response": "Xin chào! Tôi là trợ lý AI tiếng Việt."},
{"query": "Chào buổi sáng", "response": "Chào buổi sáng! Chúc bạn một ngày tốt lành."},
# Identity and purpose
{"query": "Bạn là ai?", "response": "Tôi là trợ lý AI được phát triển để hỗ trợ và trò chuyện bằng tiếng Việt."},
{"query": "Bạn từ đâu đến?", "response": "Tôi được phát triển bởi một nhóm kỹ sư AI, và tôn chỉ của tôi là hỗ trợ con người."},
# Small talk
{"query": "Bạn thích gì?", "response": "Tôi thích học hỏi và giúp đỡ mọi người. Mỗi cuộc trò chuyện là một cơ hội để tôi phát triển."},
{"query": "Bạn có thể làm gì?", "response": "Tôi có thể trò chuyện, trả lời câu hỏi, và hỗ trợ bạn trong nhiều tình huống khác nhau."},
# Weather and time
{"query": "Thời tiết hôm nay thế nào?", "response": "Xin lỗi, tôi không thể cung cấp thông tin thời tiết trực tiếp. Bạn có thể kiểm tra ứng dụng dự báo thời tiết."},
{"query": "Bây giờ là mấy giờ?", "response": "Tôi là trợ lý AI, nên không thể xem đồng hồ. Bạn có thể kiểm tra thiết bị của mình."},
# Assistance offers
{"query": "Tôi cần trợ giúp", "response": "Tôi sẵn sàng hỗ trợ bạn. Bạn cần giúp gì?"},
{"query": "Giúp tôi với cái gì đó", "response": "Vâng, tôi có thể hỗ trợ bạn. Hãy cho tôi biết chi tiết hơn."},
# Farewell
{"query": "Tạm biệt", "response": "Hẹn gặp lại! Chúc bạn một ngày tốt đẹp."},
{"query": "Bye", "response": "Tạm biệt! Rất vui được trò chuyện với bạn."},
]
@st.cache_data
def _compute_embeddings(_self): # Add underscore to self parameter
"""
Pre-compute embeddings for conversation queries
Cached to avoid recomputing on every run
"""
def embed_single_text(text, tokenizer, model):
try:
# Tokenize and generate embeddings
inputs = tokenizer(text, return_tensors='pt', padding=True, truncation=True)
with torch.no_grad():
model_output = model(**inputs)
# Mean pooling
token_embeddings = model_output[0]
input_mask_expanded = inputs['attention_mask'].unsqueeze(-1).expand(token_embeddings.size()).float()
embeddings = torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1), min=1e-9)
return embeddings.numpy()[0]
except Exception as e:
print(f"Embedding error: {e}")
return None
embeddings = []
for conversation in _self.conversation_data: # Use _self instead of self
embedding = embed_single_text(conversation['query'], _self.tokenizer, _self.model) # Use _self instead of self
if embedding is not None:
embeddings.append(embedding)
return np.array(embeddings)
def embed_text(self, text):
"""
Generate embeddings for input text
"""
try:
# Tokenize and generate embeddings
inputs = self.tokenizer(text, return_tensors='pt', padding=True, truncation=True)
with torch.no_grad():
model_output = self.model(**inputs)
# Mean pooling
embeddings = self.mean_pooling(model_output, inputs['attention_mask'])
return embeddings.numpy()
except Exception as e:
print(f"Embedding error: {e}")
return None
def mean_pooling(self, model_output, attention_mask):
"""
Perform mean pooling on model output
"""
token_embeddings = model_output[0]
input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1), min=1e-9)
def get_response(self, user_query):
"""
Find the most similar response from conversation data
"""
try:
# Embed user query
query_embedding = self.embed_text(user_query)
if query_embedding is None:
return "Xin lỗi, đã có lỗi xảy ra khi phân tích câu hỏi của bạn."
# Calculate cosine similarities
similarities = cosine_similarity(query_embedding, self.conversation_embeddings)[0]
# Find most similar response
best_match_index = np.argmax(similarities)
# Return response if similarity is above threshold
if similarities[best_match_index] > 0.5:
return self.conversation_data[best_match_index]['response']
return "Xin lỗi, tôi chưa hiểu rõ câu hỏi của bạn. Bạn có thể diễn đạt lại được không?"
except Exception as e:
print(f"Response generation error: {e}")
return "Đã xảy ra lỗi. Xin vui lòng thử lại."
@st.cache_resource
def initialize_chatbot():
"""
Cached function to initialize the chatbot
This ensures the chatbot is created only once
"""
return VietnameseChatbot()
def main():
st.set_page_config(
page_title="Trợ Lý AI Tiếng Việt",
page_icon="🤖",
)
st.title("🤖 Trợ Lý AI Tiếng Việt")
st.caption("Trò chuyện với trợ lý AI được phát triển bằng mô hình đa ngôn ngữ")
# Initialize chatbot using cached initialization
chatbot = initialize_chatbot()
# Chat history in session state
if 'messages' not in st.session_state:
st.session_state.messages = []
# Sidebar for additional information
with st.sidebar:
st.header("Về Trợ Lý AI")
st.write("Đây là một trợ lý AI được phát triển để hỗ trợ trò chuyện bằng tiếng Việt.")
st.write("Mô hình sử dụng: intfloat/multilingual-e5-small")
# Display chat messages
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# User input
if prompt := st.chat_input("Hãy nói gì đó..."):
# Add user message to chat history
st.session_state.messages.append({"role": "user", "content": prompt})
# Display user message
with st.chat_message("user"):
st.markdown(prompt)
# Get chatbot response
response = chatbot.get_response(prompt)
# Display chatbot response
with st.chat_message("assistant"):
st.markdown(response)
# Add assistant message to chat history
st.session_state.messages.append({"role": "assistant", "content": response})
if __name__ == "__main__":
main() |