Spaces:
Sleeping
Sleeping
File size: 5,670 Bytes
ac1079c 8edd424 cd75fd1 babb405 fecdf12 a8d757c 363cb8e 9088634 859a3f4 cd75fd1 2e4bd35 cd75fd1 2e4bd35 cd75fd1 ac1079c 2e4bd35 9088634 cd75fd1 2e4bd35 5d5a7f1 2e4bd35 a8d757c 2e4bd35 7eb9717 ac1079c a8d757c ac1079c cd75fd1 7eb9717 cd75fd1 fdcff15 8edd424 2e4bd35 8edd424 03f014f cd75fd1 073c315 cd75fd1 2e4bd35 cd75fd1 e3c118a c0ffbeb e3c118a 2e4bd35 babb405 16919b8 022791c 99a8b0b ac1079c 2e4bd35 c0ffbeb 439c92a c0ffbeb ac1079c 2e4bd35 ac1079c 2e4bd35 ac1079c 2e4bd35 99a8b0b 2e4bd35 ac1079c 022791c 99a8b0b |
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 |
import gradio as gr
from langchain_community.document_loaders import UnstructuredMarkdownLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_core.documents import Document
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_chroma import Chroma
from langchain.vectorstores import FAISS
from langchain_community.llms import HuggingFaceHub
from langchain.prompts import ChatPromptTemplate
from dotenv import load_dotenv
import os
import shutil
# Загрузка переменных окружения
load_dotenv()
CHROMA_PATH = "/tmp/chroma"
DATA_PATH = "" # Укажите путь к вашим данным, например "data", если файл не в корне
PROMPT_TEMPLATE = """
Ответь на вопрос, используя только следующий контекст:
{context}
---
Ответь на вопрос на основе приведенного контекста: {question}
"""
# Глобальная переменная для статуса
status_message = "Инициализация..."
def initialize_chroma():
global status_message
status_message = "Инициализация векторной базы..."
else:
status_message = "База данных Chroma уже существует. Пересоздаем базу данных..."
shutil.rmtree(CHROMA_PATH)
generate_data_store()
status_message = "База данных Chroma создана и подготовлена."
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/paraphrase-multilingual-mpnet-base-v2",
cache_folder="/tmp/model_cache",
model_kwargs={'device': 'cpu'},
encode_kwargs={'normalize_embeddings': True}
)
db = Chroma(
persist_directory=CHROMA_PATH,
embedding_function=embeddings
)
return db
def generate_data_store():
documents = load_documents()
if not documents:
raise Exception("Документы не загружены!")
chunks = split_text(documents)
status_message = f"Первые 50 символов первого чанка: {chunks[0].page_content[:50]}"
save_to_chroma(chunks)
def load_documents():
file_path = os.path.join(DATA_PATH, "pl250320252.md")
if not os.path.exists(file_path):
global status_message
status_message = f"Ошибка: Файл {file_path} не найден."
return []
loader = UnstructuredMarkdownLoader(file_path)
documents = loader.load()
return documents
def split_text(documents: list[Document]):
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=900,
chunk_overlap=300,
length_function=len,
add_start_index=True,
)
chunks = text_splitter.split_documents(documents)
global status_message
status_message += f"\nРазделено {len(documents)} документов на {len(chunks)} частей."
return chunks
def save_to_chroma(chunks: list[Document]):
if os.path.exists(CHROMA_PATH):
shutil.rmtree(CHROMA_PATH)
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/paraphrase-multilingual-mpnet-base-v2",
model_kwargs={'device': 'cpu', 'trust_remote_code': True},
encode_kwargs={'normalize_embeddings': False} # Экспериментируйте с этим
)
Chroma.from_documents(
chunks,
embeddings,
persist_directory=CHROMA_PATH
)
def process_query(query_text: str, db):
results = db.similarity_search_with_relevance_scores(query_text, k=3)
global status_message
status_message += f"\nНайдено {len(results)} результатов с релевантностью: {[round(score, 2) for _, score in results]}"
if not results:
return "Не найдено подходящих результатов.", []
if results[0][1] < 0.5:
response = "Нет высококачественных совпадений. Возможные варианты:\n"
response += "\n".join([f"- {doc.page_content[:50]}..." for doc, _ in results])
return response, [doc.metadata.get("source") for doc, _ in results]
context_text = "\n\n---\n\n".join([doc.page_content for doc, _ in results])
prompt_template = ChatPromptTemplate.from_template(PROMPT_TEMPLATE)
prompt = prompt_template.format(context=context_text, question=query_text)
model = HuggingFaceHub(
repo_id="google/flan-t5-small",
model_kwargs={"temperature": 0.5, "max_length": 512}
)
response_text = model.predict(prompt)
sources = [doc.metadata.get("source", None) for doc, _ in results]
return response_text, sources
def chat_interface(query_text):
global status_message
db = initialize_chroma()
response, sources = process_query(query_text, db)
full_response = f"{status_message}\n\nОтвет: {response}\n\nИсточники: {', '.join(sources) if sources else 'Нет источников'}"
return full_response
# Создание папок
os.makedirs("/tmp/model_cache", exist_ok=True)
os.makedirs("/tmp/chroma", exist_ok=True)
# Интерфейс Gradio
interface = gr.Interface(
fn=chat_interface,
inputs=gr.Textbox(lines=2, placeholder="Введите ваш вопрос здесь..."),
outputs="text",
title="Чат с документами",
description="Задайте вопрос, и я отвечу на основе загруженных документов."
)
if __name__ == "__main__":
interface.launch() |