Wplotnikow commited on
Commit
14a84c2
·
verified ·
1 Parent(s): 1da68e3

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +111 -0
app.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import glob
3
+ from docx import Document
4
+ from sklearn.feature_extraction.text import TfidfVectorizer
5
+ from sklearn.metrics.pairwise import cosine_similarity
6
+
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:
14
+ return ["Файл .docx не найден!"]
15
+ doc = Document(docx_list[0])
16
+ blocks = []
17
+ # Абзацы
18
+ for p in doc.paragraphs:
19
+ txt = p.text.strip()
20
+ if txt and not (len(txt) <= 3 and txt.isdigit()):
21
+ blocks.append(txt)
22
+ # Таблицы
23
+ for table in doc.tables:
24
+ for row in table.rows:
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:
32
+ if b not in seen:
33
+ uniq_blocks.append(b)
34
+ seen.add(b)
35
+ return uniq_blocks
36
+
37
+ 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()
45
+ device = 'cpu'
46
+
47
+ 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=200, num_beams=4)
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
+ best_idx = sims.argmax()
64
+ best_block = blocks[best_idx]
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 context:
74
+ return f"**Ответ:** {answer}\n\n---\n**Релевантный фрагмент из документа:**\n{context}"
75
+ else:
76
+ return f"**Ответ:** {answer}\n\n(Контекст в документе не найден — ответ дан на основе общего знания модели.)"
77
+
78
+ EXAMPLES = [
79
+ "Какие требования к объему магистерской диссертации?",
80
+ "Как оформить список литературы?",
81
+ "Какие сроки сдачи и защиты ВКР?",
82
+ "Что должно быть во введении?",
83
+ "Какой процент оригинальности требуется?",
84
+ "Как оформлять формулы?"
85
+ ]
86
+
87
+ with gr.Blocks() as demo:
88
+ gr.Markdown(
89
+ """
90
+ # Русскоязычный FAQ-чат-бот на базе вашей методички и нейросетевой модели
91
+
92
+ Задайте вопрос — получайте свежий AI-ответ, опирающийся на ваш документ!
93
+ """
94
+ )
95
+ question = gr.Textbox(label="Ваш вопрос", lines=2)
96
+ ask_btn = gr.Button("Получить ответ")
97
+ answer = gr.Markdown(label="Ответ", visible=True)
98
+ ask_btn.click(ask_chatbot, question, answer)
99
+ question.submit(ask_chatbot, question, answer)
100
+ gr.Markdown("#### Примеры вопросов:")
101
+ gr.Examples(EXAMPLES, inputs=question)
102
+ gr.Markdown("""
103
+ ---
104
+
105
+ ### Контакты (укажите свои)
106
+ Преподаватель: ___________________
107
+ Email: ___________________________
108
+ Кафедра: _________________________
109
+ """)
110
+
111
+ demo.launch()