Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -7,7 +7,6 @@ from sklearn.metrics.pairwise import cosine_similarity
|
|
| 7 |
import torch
|
| 8 |
from transformers import T5ForConditionalGeneration, T5Tokenizer
|
| 9 |
|
| 10 |
-
# 1. Получение текстов из абзацев и таблиц .docx
|
| 11 |
def get_blocks_from_docx():
|
| 12 |
docx_list = glob.glob("*.docx")
|
| 13 |
if not docx_list:
|
|
@@ -25,7 +24,6 @@ def get_blocks_from_docx():
|
|
| 25 |
row_text = " | ".join(cell.text.strip() for cell in row.cells if cell.text.strip())
|
| 26 |
if row_text:
|
| 27 |
blocks.append(row_text)
|
| 28 |
-
# Удаляем дубли
|
| 29 |
seen = set()
|
| 30 |
uniq_blocks = []
|
| 31 |
for b in blocks:
|
|
@@ -38,7 +36,6 @@ blocks = get_blocks_from_docx()
|
|
| 38 |
vectorizer = TfidfVectorizer().fit(blocks)
|
| 39 |
matrix = vectorizer.transform(blocks)
|
| 40 |
|
| 41 |
-
# 2. Загрузка модели rut5-base-multitask
|
| 42 |
tokenizer = T5Tokenizer.from_pretrained("cointegrated/rut5-base-multitask")
|
| 43 |
model = T5ForConditionalGeneration.from_pretrained("cointegrated/rut5-base-multitask")
|
| 44 |
model.eval()
|
|
@@ -48,32 +45,24 @@ def rut5_answer(question, context):
|
|
| 48 |
prompt = f"question: {question} context: {context}"
|
| 49 |
input_ids = tokenizer(prompt, return_tensors="pt").input_ids.to(device)
|
| 50 |
with torch.no_grad():
|
| 51 |
-
output_ids = model.generate(input_ids, max_length=
|
| 52 |
return tokenizer.decode(output_ids[0], skip_special_tokens=True)
|
| 53 |
|
| 54 |
-
# 3. Комбинированная функция: поиск + генерация
|
| 55 |
def ask_chatbot(question):
|
| 56 |
if not question.strip():
|
| 57 |
return "Пожалуйста, введите вопрос."
|
| 58 |
if len(blocks) < 2:
|
| 59 |
return "Ошибка: база знаний пуста или слишком мала. Проверьте .docx."
|
| 60 |
-
#
|
| 61 |
user_vec = vectorizer.transform([question])
|
| 62 |
sims = cosine_similarity(user_vec, matrix)[0]
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
score = sims[best_idx]
|
| 66 |
-
if score < 0.12:
|
| 67 |
-
context = ""
|
| 68 |
-
else:
|
| 69 |
-
context = best_block
|
| 70 |
-
# Генерируем нейросетевой ответ на русском с учетом найденного контекста
|
| 71 |
answer = rut5_answer(question, context)
|
| 72 |
-
#
|
| 73 |
-
if
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
return f"**Ответ:** {answer}\n\n(Контекст в документе не найден — ответ дан на основе общего знания модели.)"
|
| 77 |
|
| 78 |
EXAMPLES = [
|
| 79 |
"Какие требования к объему магистерской диссертации?",
|
|
@@ -89,7 +78,7 @@ with gr.Blocks() as demo:
|
|
| 89 |
"""
|
| 90 |
# Русскоязычный FAQ-чат-бот на базе вашей методички и нейросетевой модели
|
| 91 |
|
| 92 |
-
Задайте вопрос —
|
| 93 |
"""
|
| 94 |
)
|
| 95 |
question = gr.Textbox(label="Ваш вопрос", lines=2)
|
|
@@ -98,7 +87,8 @@ with gr.Blocks() as demo:
|
|
| 98 |
ask_btn.click(ask_chatbot, question, answer)
|
| 99 |
question.submit(ask_chatbot, question, answer)
|
| 100 |
gr.Markdown("#### Примеры вопросов:")
|
| 101 |
-
|
|
|
|
| 102 |
gr.Markdown("""
|
| 103 |
---
|
| 104 |
|
|
|
|
| 7 |
import torch
|
| 8 |
from transformers import T5ForConditionalGeneration, T5Tokenizer
|
| 9 |
|
|
|
|
| 10 |
def get_blocks_from_docx():
|
| 11 |
docx_list = glob.glob("*.docx")
|
| 12 |
if not docx_list:
|
|
|
|
| 24 |
row_text = " | ".join(cell.text.strip() for cell in row.cells if cell.text.strip())
|
| 25 |
if row_text:
|
| 26 |
blocks.append(row_text)
|
|
|
|
| 27 |
seen = set()
|
| 28 |
uniq_blocks = []
|
| 29 |
for b in blocks:
|
|
|
|
| 36 |
vectorizer = TfidfVectorizer().fit(blocks)
|
| 37 |
matrix = vectorizer.transform(blocks)
|
| 38 |
|
|
|
|
| 39 |
tokenizer = T5Tokenizer.from_pretrained("cointegrated/rut5-base-multitask")
|
| 40 |
model = T5ForConditionalGeneration.from_pretrained("cointegrated/rut5-base-multitask")
|
| 41 |
model.eval()
|
|
|
|
| 45 |
prompt = f"question: {question} context: {context}"
|
| 46 |
input_ids = tokenizer(prompt, return_tensors="pt").input_ids.to(device)
|
| 47 |
with torch.no_grad():
|
| 48 |
+
output_ids = model.generate(input_ids, max_length=250, num_beams=4, min_length=40, no_repeat_ngram_size=3)
|
| 49 |
return tokenizer.decode(output_ids[0], skip_special_tokens=True)
|
| 50 |
|
|
|
|
| 51 |
def ask_chatbot(question):
|
| 52 |
if not question.strip():
|
| 53 |
return "Пожалуйста, введите вопрос."
|
| 54 |
if len(blocks) < 2:
|
| 55 |
return "Ошибка: база знаний пуста или слишком мала. Проверьте .docx."
|
| 56 |
+
# Берём ТРИ лучших блока для большего контекста (больше данных для генерации)
|
| 57 |
user_vec = vectorizer.transform([question])
|
| 58 |
sims = cosine_similarity(user_vec, matrix)[0]
|
| 59 |
+
top_idxs = sims.argsort()[-3:][::-1]
|
| 60 |
+
context = " ".join([blocks[i] for i in top_idxs if sims[i] > 0.08])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
answer = rut5_answer(question, context)
|
| 62 |
+
# Проверяем: выдаём только развёрнутые (2 предложения и более) или повторяем часть исходника как расширение
|
| 63 |
+
if len(answer.split('.')) < 2:
|
| 64 |
+
answer += "\n\n" + context
|
| 65 |
+
return answer
|
|
|
|
| 66 |
|
| 67 |
EXAMPLES = [
|
| 68 |
"Какие требования к объему магистерской диссертации?",
|
|
|
|
| 78 |
"""
|
| 79 |
# Русскоязычный FAQ-чат-бот на базе вашей методички и нейросетевой модели
|
| 80 |
|
| 81 |
+
Задайте вопрос — получите развернутый AI-ответ на русском языке на основании вашего документа!
|
| 82 |
"""
|
| 83 |
)
|
| 84 |
question = gr.Textbox(label="Ваш вопрос", lines=2)
|
|
|
|
| 87 |
ask_btn.click(ask_chatbot, question, answer)
|
| 88 |
question.submit(ask_chatbot, question, answer)
|
| 89 |
gr.Markdown("#### Примеры вопросов:")
|
| 90 |
+
for ex in EXAMPLES:
|
| 91 |
+
gr.Markdown(f"- {ex}")
|
| 92 |
gr.Markdown("""
|
| 93 |
---
|
| 94 |
|