Spaces:
Sleeping
Sleeping
File size: 4,170 Bytes
0f8f1e7 86841b5 0f8f1e7 86841b5 0f8f1e7 86841b5 |
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 |
import os
import gradio as gr
from datasets import load_dataset, concatenate_datasets
from langchain.docstore.document import Document
from langchain.vectorstores import FAISS
from langchain_huggingface import HuggingFaceEmbeddings
from tqdm import tqdm
# load env
from dotenv import load_dotenv
load_dotenv()
key = os.getenv("HF_KEY")
# Путь для сохранения FAISS-индекса
INDEX_PATH = "./faiss_index"
# Инициализируем эмбеддинг-модель (используем модель из Hugging Face)
embeddings = HuggingFaceEmbeddings(model_name="fitlemon/bge-m3-uz-legal-matryoshka")
def update_faiss_index():
"""
Загружает датасет, преобразует данные в документы с метаданными,
создаёт FAISS-индекс и сохраняет его локально.
"""
# Загружаем датасет (например, сплит "train")
train_dataset = load_dataset("fitlemon/rag-labor-codex-dataset", token=key)["train"]
test_dataset = load_dataset("fitlemon/rag-labor-codex-dataset", token=key)["test"]
# combine train and test datasets
dataset = concatenate_datasets([train_dataset, test_dataset])
# get rid off duplicate chunks
docs = []
unique_chunks = set()
for row in tqdm(dataset, desc="Загрузка документов..."):
chunk = row["chunk"]
# Если chunk уже добавлен, пропускаем его
if chunk in unique_chunks:
continue
unique_chunks.add(chunk)
doc = Document(
page_content=chunk,
metadata={
"section": row["section"],
"section_name": row["section_name"],
"chapter_name": row["chapter"],
},
)
docs.append(doc)
print(f"Документы успешно загружены и преобразованы. Длина документов: {len(docs)}")
# Создаём FAISS-индекс на основе документов
db = FAISS.from_documents(docs, embeddings)
# Сохраняем индекс в указанную директорию
os.makedirs(INDEX_PATH, exist_ok=True)
db.save_local(INDEX_PATH)
print("FAISS индекс обновлён и сохранён в:", INDEX_PATH)
return db
# Если индекс ещё не создан, обновляем его, иначе загружаем существующий
if not os.path.exists(INDEX_PATH):
db = update_faiss_index()
else:
db = FAISS.load_local(INDEX_PATH, embeddings, allow_dangerous_deserialization=True)
print("Загружен существующий FAISS индекс из:", INDEX_PATH)
def retrieve_articles(query):
"""
Принимает запрос пользователя, ищет в FAISS-индексе топ-3 наиболее релевантных документа
и возвращает отформатированный результат в Markdown.
"""
# Поиск по индексу: возвращает список из документов
results = db.similarity_search(query, k=3)
# Форматируем результаты для вывода
result_text = ""
for doc in results:
result_text += (
f"### Статья {doc.metadata['section']}: {doc.metadata['section_name']}\n"
)
result_text += f"**Глава:** {doc.metadata['chapter_name']}\n\n"
result_text += f"**Текст статьи:**\n{doc.page_content}\n\n"
result_text += "---\n\n"
return result_text
# Создаём Gradio-интерфейс
iface = gr.Interface(
fn=retrieve_articles,
inputs=gr.Textbox(lines=3, placeholder="Введите ваш вопрос о кодексе..."),
outputs=gr.Markdown(),
title="Поиск по Кодексу через FAISS",
description="Введите вопрос, и получите топ-3 наиболее релевантные статьи из кодекса.",
)
if __name__ == "__main__":
iface.launch()
|