Loversofdeath commited on
Commit
2782135
·
verified ·
1 Parent(s): 301371a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +123 -61
app.py CHANGED
@@ -3,73 +3,105 @@ import os
3
  from langdetect import detect
4
  from sentence_transformers import SentenceTransformer
5
  import numpy as np
 
6
 
7
- # Загрузка текстовых файлов
8
- def load_text_files():
9
  files = {
10
  "vampires": "vampires.txt",
11
  "werewolves": "werewolves.txt",
12
  "humans": "humans.txt"
13
  }
14
 
15
- loaded_data = {}
16
- for key, filename in files.items():
17
  try:
18
  with open(filename, 'r', encoding='utf-8') as file:
19
- loaded_data[key] = file.read()
 
 
 
20
  except FileNotFoundError:
21
  print(f"Файл {filename} не найден")
22
- loaded_data[key] = ""
23
 
24
- return loaded_data
25
 
26
- # Инициализация модели для поиска (легковесная)
27
  def initialize_search_model():
28
  return SentenceTransformer('sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2')
29
 
30
- # Поиск наиболее релевантных фрагментов
31
- def find_relevant_text(question, text_data, model, top_k=3):
32
- # Разбиваем тексты на предложения
33
- sentences = []
34
- sources = []
35
- for category, text in text_data.items():
36
- if text:
37
- for sentence in text.split('\n'):
38
- if sentence.strip():
39
- sentences.append(sentence.strip())
40
- sources.append(category)
41
-
42
- if not sentences:
43
- return "Нет данных для анализа"
44
-
45
- # Эмбеддинги для предложений и вопроса
46
- sentence_embeddings = model.encode(sentences)
47
  question_embedding = model.encode([question])
48
 
49
- # Поиск наиболее похожих предложений
50
- similarities = np.dot(sentence_embeddings, question_embedding.T).flatten()
51
  top_indices = similarities.argsort()[-top_k:][::-1]
52
 
53
- # Формируем контекст
54
- context = "Контекст:\n"
55
- for idx in top_indices:
56
- context += f"[Из {sources[idx]}]: {sentences[idx]}\n"
57
-
58
- return context
59
-
60
- # Генерация ответа (упрощенная)
61
- def generate_answer(question, context):
62
- # Простейшая логика ответа без LLM
63
- if not context.strip():
64
- return "Извините, не могу найти информацию по вашему вопросу."
65
-
66
- return f"""На основе имеющейся информации:
67
 
68
- {context}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
- Это все, что я могу сказать по данному вопросу. Если вам нужны более подробные сведения, уточните вопрос."""
71
-
72
- # Основная функция обработки
73
  def process_question(question, history):
74
  # Проверка языка
75
  try:
@@ -79,34 +111,64 @@ def process_question(question, history):
79
  pass
80
 
81
  # Ленивая загрузка данных и модели
82
- if not hasattr(process_question, 'text_data'):
83
- process_question.text_data = load_text_files()
84
 
85
  if not hasattr(process_question, 'search_model'):
86
  process_question.search_model = initialize_search_model()
87
 
88
  # Поиск релевантной информации
89
- context = find_relevant_text(question, process_question.text_data, process_question.search_model)
90
 
91
- # Формирование ответа
92
- answer = generate_answer(question, context)
93
 
94
  # Обновление истории
95
  history.append((question, answer))
96
 
97
  return "", history
98
 
99
- # Создание интерфейса
100
- with gr.Blocks() as demo:
101
- gr.Markdown("## 📚 Чат-бот с доступом к текстовым файлам")
102
- gr.Markdown("Задавайте вопросы о вампирах, оборотнях или людях")
103
-
104
- chatbot = gr.Chatbot(label="Диалог", height=400)
105
- msg = gr.Textbox(label="Ваш вопрос", placeholder="Введите вопрос на русском языке...")
106
- clear = gr.Button("Очистить чат")
107
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  msg.submit(process_question, [msg, chatbot], [msg, chatbot])
109
  clear.click(lambda: None, None, chatbot, queue=False)
110
 
111
- # Запуск приложения с ограничением ресурсов
112
- demo.launch(server_name="0.0.0.0", server_port=7860, show_error=True)
 
3
  from langdetect import detect
4
  from sentence_transformers import SentenceTransformer
5
  import numpy as np
6
+ import re
7
 
8
+ # Загрузка и предварительная обработка текстовых файлов
9
+ def load_and_preprocess_files():
10
  files = {
11
  "vampires": "vampires.txt",
12
  "werewolves": "werewolves.txt",
13
  "humans": "humans.txt"
14
  }
15
 
16
+ knowledge_base = {}
17
+ for category, filename in files.items():
18
  try:
19
  with open(filename, 'r', encoding='utf-8') as file:
20
+ content = file.read()
21
+ # Разбиваем на осмысленные блоки (абзацы)
22
+ paragraphs = [p.strip() for p in content.split('\n\n') if p.strip()]
23
+ knowledge_base[category] = paragraphs
24
  except FileNotFoundError:
25
  print(f"Файл {filename} не найден")
26
+ knowledge_base[category] = []
27
 
28
+ return knowledge_base
29
 
30
+ # Инициализация модели для семантического поиска
31
  def initialize_search_model():
32
  return SentenceTransformer('sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2')
33
 
34
+ # Поиск релевантной информации с улучшенным ранжированием
35
+ def find_relevant_info(question, knowledge_base, model, top_k=3):
36
+ # Собираем все текстовые фрагменты с их категориями
37
+ all_fragments = []
38
+ for category, paragraphs in knowledge_base.items():
39
+ for para in paragraphs:
40
+ all_fragments.append((para, category))
41
+
42
+ if not all_fragments:
43
+ return []
44
+
45
+ # Эмбеддинги для всех фрагментов
46
+ texts = [f[0] for f in all_fragments]
47
+ embeddings = model.encode(texts)
 
 
 
48
  question_embedding = model.encode([question])
49
 
50
+ # Вычисляем сходство и выбираем топ фрагментов
51
+ similarities = np.dot(embeddings, question_embedding.T).flatten()
52
  top_indices = similarities.argsort()[-top_k:][::-1]
53
 
54
+ return [all_fragments[i] for i in top_indices]
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
+ # Генерация естественного ответа
57
+ def generate_natural_response(question, relevant_info):
58
+ if not relevant_info:
59
+ return "Извините, не нашел информации по вашему вопросу. Попробуйте переформулировать."
60
+
61
+ # Определяем тему вопроса
62
+ question_type = "о них"
63
+ if "вампир" in question.lower():
64
+ question_type = "о вампирах"
65
+ elif "оборотн" in question.lower() or "волколак" in question.lower():
66
+ question_type = "об оборотнях"
67
+ elif "человек" in question.lower() or "люди" in question.lower():
68
+ question_type = "о людях"
69
+
70
+ # Собираем уникальную информацию
71
+ unique_info = []
72
+ seen = set()
73
+ for para, category in relevant_info:
74
+ if para not in seen:
75
+ unique_info.append((para, category))
76
+ seen.add(para)
77
+
78
+ # Формируем ответ
79
+ response = f"Вот чт�� мне известно {question_type}:\n\n"
80
+
81
+ for i, (para, category) in enumerate(unique_info, 1):
82
+ # Упрощаем маркированные списки
83
+ if para.startswith("- "):
84
+ para = para.replace("\n- ", "\n• ").replace("- ", "• ")
85
+
86
+ # Добавляем источник только если есть несколько категорий
87
+ if len(set(c for _, c in unique_info)) > 1:
88
+ response += f"{i}. ({category.capitalize()}) {para}\n\n"
89
+ else:
90
+ response += f"{i}. {para}\n\n"
91
+
92
+ # Добавляем естественное завершение
93
+ endings = [
94
+ "Надеюсь, эта информация была полезной!",
95
+ "Если хотите узнать больше деталей, уточните вопрос.",
96
+ "Могу уточнить какие-то моменты, если нужно.",
97
+ "Это основные сведения, которые у меня есть."
98
+ ]
99
+
100
+ response += np.random.choice(endings)
101
+
102
+ return response
103
 
104
+ # Обработка вопроса с улучшенной логикой
 
 
105
  def process_question(question, history):
106
  # Проверка языка
107
  try:
 
111
  pass
112
 
113
  # Ленивая загрузка данных и модели
114
+ if not hasattr(process_question, 'knowledge_base'):
115
+ process_question.knowledge_base = load_and_preprocess_files()
116
 
117
  if not hasattr(process_question, 'search_model'):
118
  process_question.search_model = initialize_search_model()
119
 
120
  # Поиск релевантной информации
121
+ relevant_info = find_relevant_info(question, process_question.knowledge_base, process_question.search_model)
122
 
123
+ # Генерация ответа
124
+ answer = generate_natural_response(question, relevant_info)
125
 
126
  # Обновление истории
127
  history.append((question, answer))
128
 
129
  return "", history
130
 
131
+ # Создание интерфейса с улучшенным дизайном
132
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
133
+ gr.Markdown("""<h1 style='text-align: center'>🧛‍♂️ Мир сверхъестественного 🐺</h1>""")
134
+ gr.Markdown("""<div style='text-align: center'>Задавайте вопросы о вампирах, оборотнях и людях на русском языке</div>""")
135
+
136
+ with gr.Row():
137
+ with gr.Column(scale=2):
138
+ chatbot = gr.Chatbot(
139
+ label="Диалог",
140
+ bubble_full_width=False,
141
+ avatar_images=(
142
+ "https://i.imgur.com/7WqjWaz.png", # User avatar
143
+ "https://i.imgur.com/7uQWsZg.png" # Bot avatar
144
+ ),
145
+ height=500
146
+ )
147
+ with gr.Column(scale=1):
148
+ gr.Markdown("**Примеры вопросов:**")
149
+ gr.Examples(
150
+ examples=[
151
+ "Какие слабости у вампиров?",
152
+ "Как защититься от оборотней?",
153
+ "Чем люди отличаются от других существ?",
154
+ "Расскажи подробнее о вампирах"
155
+ ],
156
+ inputs=[msg]
157
+ )
158
+
159
+ msg = gr.Textbox(
160
+ label="Ваш вопрос",
161
+ placeholder="Введите вопрос и нажмите Enter...",
162
+ container=False
163
+ )
164
+
165
+ with gr.Row():
166
+ submit = gr.Button("Отправить", variant="primary")
167
+ clear = gr.Button("Очистить историю")
168
+
169
+ submit.click(process_question, [msg, chatbot], [msg, chatbot])
170
  msg.submit(process_question, [msg, chatbot], [msg, chatbot])
171
  clear.click(lambda: None, None, chatbot, queue=False)
172
 
173
+ # Запуск приложения
174
+ demo.launch(server_name="0.0.0.0", server_port=7860)