Upload 7 files
Browse files- .gitattributes +35 -35
- Dockerfile +42 -21
- README.md +10 -19
- app.py +38 -0
- generation.py +78 -0
- requirements.txt +11 -3
- retrieval.py +69 -0
.gitattributes
CHANGED
|
@@ -1,35 +1,35 @@
|
|
| 1 |
-
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
-
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
-
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
-
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
-
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
-
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
-
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
-
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
-
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
-
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
-
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
-
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
-
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
-
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
-
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
-
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
-
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
-
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
-
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
-
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
-
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
-
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
-
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
-
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
-
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
-
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
-
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
-
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
-
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
-
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
-
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
-
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
-
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
-
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
-
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
Dockerfile
CHANGED
|
@@ -1,21 +1,42 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
RUN
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Use the official Python image from the Docker Hub
|
| 2 |
+
FROM python:3.10-slim
|
| 3 |
+
|
| 4 |
+
# Set up a new user named "user" with user ID 1000
|
| 5 |
+
RUN useradd -m -u 1000 user
|
| 6 |
+
|
| 7 |
+
# Set environment variables for the cache directory (use a writable directory)
|
| 8 |
+
ENV TRANSFORMERS_CACHE=/home/user/.cache/huggingface
|
| 9 |
+
|
| 10 |
+
# Create and set the cache directory so the user can write to it
|
| 11 |
+
RUN mkdir -p /home/user/.cache/huggingface && chown -R user:user /home/user/.cache
|
| 12 |
+
|
| 13 |
+
# Switch to the "user" user
|
| 14 |
+
USER user
|
| 15 |
+
|
| 16 |
+
# Set home to the user's home directory
|
| 17 |
+
ENV HOME=/home/user \
|
| 18 |
+
PATH=/home/user/.local/bin:$PATH
|
| 19 |
+
|
| 20 |
+
# Set the working directory to the user's home directory
|
| 21 |
+
WORKDIR $HOME/app
|
| 22 |
+
|
| 23 |
+
# Upgrade pip to the latest version to avoid issues with outdated pip
|
| 24 |
+
RUN pip install --no-cache-dir --upgrade pip
|
| 25 |
+
|
| 26 |
+
# Copy the current directory contents into the container at $HOME/app setting the owner to the user
|
| 27 |
+
COPY --chown=user . $HOME/app
|
| 28 |
+
|
| 29 |
+
# Install dependencies
|
| 30 |
+
RUN pip install --no-cache-dir -r requirements.txt
|
| 31 |
+
|
| 32 |
+
# Download any necessary assets
|
| 33 |
+
RUN mkdir content
|
| 34 |
+
ADD --chown=user https://huggingface.co/datasets/manhteky123/LawVietnamese/resolve/main/data.csv content/data.csv
|
| 35 |
+
ADD --chown=user https://huggingface.co/datasets/manhteky123/LawVietnamese/resolve/main/faiss_index.bin content/faiss_index.bin
|
| 36 |
+
ADD --chown=user https://huggingface.co/datasets/manhteky123/LawVietnamese/resolve/main/vectors.npy content/vectors.npy
|
| 37 |
+
|
| 38 |
+
# Expose the port the app runs on
|
| 39 |
+
EXPOSE 5000
|
| 40 |
+
|
| 41 |
+
# Define the command to run the application
|
| 42 |
+
CMD ["python", "app.py"]
|
README.md
CHANGED
|
@@ -1,19 +1,10 @@
|
|
| 1 |
-
---
|
| 2 |
-
title:
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 6 |
-
sdk: docker
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
short_description: Streamlit template space
|
| 12 |
-
---
|
| 13 |
-
|
| 14 |
-
# Welcome to Streamlit!
|
| 15 |
-
|
| 16 |
-
Edit `/src/streamlit_app.py` to customize this app to your heart's desire. :heart:
|
| 17 |
-
|
| 18 |
-
If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
|
| 19 |
-
forums](https://discuss.streamlit.io).
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: VN Law Chat
|
| 3 |
+
emoji: 👁
|
| 4 |
+
colorFrom: indigo
|
| 5 |
+
colorTo: green
|
| 6 |
+
sdk: docker
|
| 7 |
+
pinned: false
|
| 8 |
+
---
|
| 9 |
+
|
| 10 |
+
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from flask import Flask, request, jsonify, render_template, session
|
| 2 |
+
from retrieval import retrieve_documents
|
| 3 |
+
from generation import generate_response
|
| 4 |
+
import os
|
| 5 |
+
|
| 6 |
+
app = Flask(__name__)
|
| 7 |
+
app.secret_key = os.urandom(24) # Set a secret key for session management
|
| 8 |
+
|
| 9 |
+
@app.route('/')
|
| 10 |
+
def index():
|
| 11 |
+
return render_template('index.html')
|
| 12 |
+
|
| 13 |
+
@app.route('/retrieve', methods=['POST'])
|
| 14 |
+
def retrieve():
|
| 15 |
+
query = request.json.get('query')
|
| 16 |
+
documents = retrieve_documents(query)
|
| 17 |
+
return jsonify(documents)
|
| 18 |
+
|
| 19 |
+
@app.route('/generate', methods=['POST'])
|
| 20 |
+
def generate():
|
| 21 |
+
context = request.json.get('context')
|
| 22 |
+
retrieved_data = request.json.get('retrieved_data', [])
|
| 23 |
+
|
| 24 |
+
# Get the conversation history from the session
|
| 25 |
+
conversation_history = session.get('conversation_history', [])
|
| 26 |
+
conversation_history.append(context)
|
| 27 |
+
session['conversation_history'] = conversation_history
|
| 28 |
+
|
| 29 |
+
response = generate_response(context, retrieved_data, conversation_history)
|
| 30 |
+
return jsonify(response)
|
| 31 |
+
|
| 32 |
+
@app.route('/reset', methods=['POST'])
|
| 33 |
+
def reset():
|
| 34 |
+
session.pop('conversation_history', None)
|
| 35 |
+
return jsonify({"message": "Conversation history reset."})
|
| 36 |
+
|
| 37 |
+
if __name__ == "__main__":
|
| 38 |
+
app.run(host="0.0.0.0", port=7860)
|
generation.py
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import google.generativeai as genai
|
| 2 |
+
|
| 3 |
+
# Configure the API key
|
| 4 |
+
genai.configure(api_key="AIzaSyBHAbEv8rMAbhAoBWXsubsUHqwP-EAlp6I")
|
| 5 |
+
|
| 6 |
+
from google.generativeai.types import HarmCategory, HarmBlockThreshold
|
| 7 |
+
|
| 8 |
+
safe = {
|
| 9 |
+
"HARM_CATEGORY_HARASSMENT": "BLOCK_NONE",
|
| 10 |
+
"HARM_CATEGORY_HATE_SPEECH": "BLOCK_NONE",
|
| 11 |
+
"HARM_CATEGORY_SEXUALLY_EXPLICIT": "BLOCK_NONE",
|
| 12 |
+
"HARM_CATEGORY_DANGEROUS_CONTENT": "BLOCK_NONE",
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
def generate_response(context, retrieved_data, conversation_history):
|
| 16 |
+
"""
|
| 17 |
+
Generate a response using a generative AI model in a Retrieval-Augmented Generation (RAG) setup.
|
| 18 |
+
|
| 19 |
+
Parameters:
|
| 20 |
+
context (str): The user's question or query.
|
| 21 |
+
retrieved_data (str): Relevant information retrieved from the database.
|
| 22 |
+
conversation_history (list): List of previous questions in the conversation.
|
| 23 |
+
|
| 24 |
+
Returns:
|
| 25 |
+
str: The response generated by the model.
|
| 26 |
+
"""
|
| 27 |
+
# Select the appropriate model
|
| 28 |
+
model = genai.GenerativeModel("gemini-2.0-flash")
|
| 29 |
+
|
| 30 |
+
# Construct the prompt based on the availability of retrieved data
|
| 31 |
+
if conversation_history:
|
| 32 |
+
history = "\n".join(conversation_history)
|
| 33 |
+
if retrieved_data:
|
| 34 |
+
prompt = (
|
| 35 |
+
"Bạn là một chuyên gia tư vấn luật pháp hàng đầu tại Việt Nam với kiến thức sâu rộng và kinh nghiệm thực tiễn. "
|
| 36 |
+
"Dựa trên các thông tin được cung cấp dưới đây, hãy đưa ra câu trả lời chi tiết, dễ hiểu và có tính chuyên nghiệp cao để hỗ trợ người dùng:\n"
|
| 37 |
+
"--- Thông tin tham khảo ---\n"
|
| 38 |
+
f"{retrieved_data}\n\n"
|
| 39 |
+
"--- Lịch sử cuộc trò chuyện ---\n"
|
| 40 |
+
f"{history}\n\n"
|
| 41 |
+
"--- Câu hỏi hiện tại của người dùng ---\n"
|
| 42 |
+
f"{context}\n\n"
|
| 43 |
+
"Hãy đảm bảo câu trả lời được trình bày một cách rõ ràng, chính xác, và phù hợp với ngữ cảnh pháp lý tại Việt Nam."
|
| 44 |
+
)
|
| 45 |
+
else:
|
| 46 |
+
prompt = (
|
| 47 |
+
"Bạn là một chuyên gia tư vấn luật pháp hàng đầu tại Việt Nam. "
|
| 48 |
+
"Hiện tại, không có thông tin cụ thể nào để hỗ trợ trả lời câu hỏi của người dùng. "
|
| 49 |
+
"Vui lòng yêu cầu người dùng cung cấp thêm thông tin chi tiết hoặc hướng dẫn họ tập trung vào các khía cạnh cụ thể hơn liên quan đến luật pháp Việt Nam."
|
| 50 |
+
)
|
| 51 |
+
else:
|
| 52 |
+
if retrieved_data:
|
| 53 |
+
prompt = (
|
| 54 |
+
"Bạn là một chuyên gia tư vấn luật pháp hàng đầu tại Việt Nam với kiến thức sâu rộng và kinh nghiệm thực tiễn. "
|
| 55 |
+
"Dựa trên các thông tin được cung cấp dưới đây, hãy đưa ra câu trả lời chi tiết, dễ hiểu và có tính chuyên nghiệp cao để hỗ trợ người dùng:\n"
|
| 56 |
+
"--- Thông tin tham khảo ---\n"
|
| 57 |
+
f"{retrieved_data}\n\n"
|
| 58 |
+
"--- Câu hỏi hiện tại của người dùng ---\n"
|
| 59 |
+
f"{context}\n\n"
|
| 60 |
+
"Hãy đảm bảo câu trả lời được trình bày một cách rõ ràng, chính xác, và phù hợp với ngữ cảnh pháp lý tại Việt Nam."
|
| 61 |
+
)
|
| 62 |
+
else:
|
| 63 |
+
prompt = (
|
| 64 |
+
"Bạn là một chuyên gia tư vấn luật pháp hàng đầu tại Việt Nam. "
|
| 65 |
+
"Hiện tại, không có thông tin cụ thể nào để hỗ trợ trả lời câu hỏi của người dùng. "
|
| 66 |
+
"Vui lòng yêu cầu người dùng cung cấp thêm thông tin chi tiết hoặc hướng dẫn họ tập trung vào các khía cạnh cụ thể hơn liên quan đến luật pháp Việt Nam."
|
| 67 |
+
)
|
| 68 |
+
|
| 69 |
+
# Generate the response using the model
|
| 70 |
+
|
| 71 |
+
try:
|
| 72 |
+
response = model.generate_content(prompt, safety_settings=safe)
|
| 73 |
+
if response and response.text:
|
| 74 |
+
return response.text.strip()
|
| 75 |
+
else:
|
| 76 |
+
return "Lỗi: Không có phản hồi từ mô hình."
|
| 77 |
+
except Exception as e:
|
| 78 |
+
return f"Đã xảy ra lỗi khi gọi mô hình: {str(e)}"
|
requirements.txt
CHANGED
|
@@ -1,3 +1,11 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Flask==2.1.2
|
| 2 |
+
google-generativeai
|
| 3 |
+
faiss-cpu==1.7.2
|
| 4 |
+
pandas==1.3.3
|
| 5 |
+
numpy==1.21.2
|
| 6 |
+
tqdm==4.62.3
|
| 7 |
+
pyngrok==5.1.0
|
| 8 |
+
requests==2.26.0
|
| 9 |
+
Werkzeug==2.2.2
|
| 10 |
+
sentence-transformers==2.2.2
|
| 11 |
+
huggingface-hub==0.11.0
|
retrieval.py
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import pandas as pd
|
| 3 |
+
from sentence_transformers import SentenceTransformer
|
| 4 |
+
import numpy as np
|
| 5 |
+
from tqdm import tqdm
|
| 6 |
+
import csv
|
| 7 |
+
import faiss
|
| 8 |
+
import requests
|
| 9 |
+
|
| 10 |
+
os.environ['TRANSFORMERS_CACHE'] = '/tmp/huggingface_cache'
|
| 11 |
+
|
| 12 |
+
# URLs of files from Hugging Face
|
| 13 |
+
base_url = "https://huggingface.co/datasets/manhteky123/LawVietnamese/resolve/main/"
|
| 14 |
+
data_url = f"{base_url}data.csv"
|
| 15 |
+
faiss_index_url = f"{base_url}faiss_index.bin"
|
| 16 |
+
vectors_url = f"{base_url}vectors.npy"
|
| 17 |
+
|
| 18 |
+
# Function to download files to disk
|
| 19 |
+
def download_to_disk(url, filename):
|
| 20 |
+
response = requests.get(url)
|
| 21 |
+
if response.status_code == 200:
|
| 22 |
+
with open(filename, 'wb') as f:
|
| 23 |
+
f.write(response.content)
|
| 24 |
+
print(f"Downloaded {url} to {filename}.")
|
| 25 |
+
else:
|
| 26 |
+
raise Exception(f"Failed to download {url}: {response.status_code}")
|
| 27 |
+
|
| 28 |
+
# Download the necessary files to disk
|
| 29 |
+
data_file_path = 'data.csv'
|
| 30 |
+
faiss_index_file_path = 'faiss_index.bin'
|
| 31 |
+
vectors_file_path = 'vectors.npy'
|
| 32 |
+
|
| 33 |
+
download_to_disk(data_url, data_file_path)
|
| 34 |
+
download_to_disk(faiss_index_url, faiss_index_file_path)
|
| 35 |
+
download_to_disk(vectors_url, vectors_file_path)
|
| 36 |
+
|
| 37 |
+
# Read the CSV data from the downloaded file
|
| 38 |
+
with open(data_file_path, 'r', encoding='utf-8') as file:
|
| 39 |
+
reader = csv.reader(file)
|
| 40 |
+
next(reader) # Skip the header row
|
| 41 |
+
data = [row[0].split(',', 2) for row in reader]
|
| 42 |
+
df = pd.DataFrame(data, columns=['so_hieu', 'dieu', 'truncated_text'])
|
| 43 |
+
|
| 44 |
+
print(df.head())
|
| 45 |
+
|
| 46 |
+
# Use the correct column name
|
| 47 |
+
column_name = 'truncated_text'
|
| 48 |
+
|
| 49 |
+
# Use the 'truncated_text' column
|
| 50 |
+
column_name = 'truncated_text'
|
| 51 |
+
|
| 52 |
+
# Load SentenceTransformer
|
| 53 |
+
model = SentenceTransformer('intfloat/multilingual-e5-small')
|
| 54 |
+
|
| 55 |
+
# Read FAISS index from file
|
| 56 |
+
index = faiss.read_index(faiss_index_file_path)
|
| 57 |
+
|
| 58 |
+
# Load vectors
|
| 59 |
+
vectors = np.load(vectors_file_path)
|
| 60 |
+
|
| 61 |
+
def retrieve_documents(query, k=5, threshold=0.7):
|
| 62 |
+
query_vector = model.encode([query], convert_to_tensor=True).cpu().numpy()
|
| 63 |
+
D, I = index.search(query_vector, k)
|
| 64 |
+
similarities = 1 / (1 + D[0])
|
| 65 |
+
filtered_documents = []
|
| 66 |
+
for i, similarity in enumerate(similarities):
|
| 67 |
+
if similarity >= threshold:
|
| 68 |
+
filtered_documents.append(df.iloc[I[0][i]][column_name])
|
| 69 |
+
return filtered_documents
|