X commited on
Commit
7b81d65
·
verified ·
1 Parent(s): a62d379

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +125 -0
app.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from datasets import load_dataset
3
+ import numpy as np
4
+ import torch
5
+ from sentence_transformers import SentenceTransformer
6
+
7
+ # ===================================================================
8
+ # 1. НАСТРОЙКИ
9
+ # ===================================================================
10
+
11
+ MODEL_NAME = "BAAI/bge-large-en-v1.5"
12
+ DATASET_NAME = "wikimedia/wikipedia"
13
+ LANGUAGE = "20231101.en" # можно заменить на "20231101.ru" для русского
14
+ ARTICLE_LIMIT = 1000 # сколько статей загрузить (для экономии памяти)
15
+
16
+ st.set_page_config(
17
+ page_title="Wikipedia Assistant",
18
+ page_icon="🌖",
19
+ layout="wide"
20
+ )
21
+
22
+ st.title("🌖 Wikipedia Assistant")
23
+ st.markdown("Задай вопрос — я найду ответ в Википедии!")
24
+
25
+ # ===================================================================
26
+ # 2. ЗАГРУЗКА ДАТАСЕТА
27
+ # ===================================================================
28
+
29
+ @st.cache_resource
30
+ def load_wikipedia():
31
+ """Загружает датасет Википедии"""
32
+ with st.spinner("📚 Загружаю Википедию..."):
33
+ dataset = load_dataset(
34
+ DATASET_NAME,
35
+ LANGUAGE,
36
+ split="train",
37
+ streaming=True
38
+ )
39
+
40
+ articles = []
41
+ for i, row in enumerate(dataset):
42
+ if i >= ARTICLE_LIMIT:
43
+ break
44
+ articles.append({
45
+ "id": row.get("id", i),
46
+ "title": row.get("title", "Без названия"),
47
+ "text": row.get("text", "")[:3000],
48
+ "url": row.get("url", "")
49
+ })
50
+
51
+ return articles
52
+
53
+ @st.cache_resource
54
+ def load_embedder():
55
+ """Загружает модель для эмбеддингов"""
56
+ with st.spinner("🧠 Загружаю модель..."):
57
+ return SentenceTransformer(MODEL_NAME)
58
+
59
+ # ===================================================================
60
+ # 3. ПОИСК
61
+ # ===================================================================
62
+
63
+ def search_wikipedia(query, articles, embedder):
64
+ """Ищет ответ на вопрос в Википедии"""
65
+ # Кодируем запрос
66
+ query_vector = embedder.encode(
67
+ [query],
68
+ normalize_embeddings=True
69
+ )[0]
70
+
71
+ # Кодируем все статьи (если ещё не закодированы)
72
+ if "embeddings" not in st.session_state:
73
+ with st.spinner("🔢 Создаю эмбеддинги статей..."):
74
+ texts = [f"{a['title']}\n\n{a['text']}" for a in articles]
75
+ embeddings = embedder.encode(
76
+ texts,
77
+ normalize_embeddings=True
78
+ )
79
+ st.session_state.embeddings = embeddings
80
+
81
+ # Ищем
82
+ scores = st.session_state.embeddings @ query_vector
83
+ top_indices = np.argsort(-scores)[:3]
84
+
85
+ results = []
86
+ for idx in top_indices:
87
+ results.append({
88
+ "article": articles[int(idx)],
89
+ "score": float(scores[int(idx)])
90
+ })
91
+
92
+ return results
93
+
94
+ # ===================================================================
95
+ # 4. ИНТЕРФЕЙС
96
+ # ===================================================================
97
+
98
+ # Загружаем данные
99
+ articles = load_wikipedia()
100
+ embedder = load_embedder()
101
+
102
+ st.success(f"✅ Загружено {len(articles)} статей")
103
+
104
+ # Поле ввода
105
+ query = st.text_input("🔍 Что хочешь узнать?", placeholder="Например: Как измеряют расстояние до галактик?")
106
+
107
+ if query:
108
+ with st.spinner("🔎 Ищу ответ..."):
109
+ results = search_wikipedia(query, articles, embedder)
110
+
111
+ # Показываем результаты
112
+ for i, result in enumerate(results, 1):
113
+ score = result["score"]
114
+ article = result["article"]
115
+
116
+ # Только если релевантно
117
+ if score > 0.3:
118
+ with st.expander(f"#{i} {article['title']} (сходство: {score:.2f})"):
119
+ st.write(article["text"][:2000] + "...")
120
+ if article["url"]:
121
+ st.link_button("🔗 Читать на Википедии", article["url"])
122
+ else:
123
+ st.warning("😕 Не нашёл подходящей статьи. Попробуй уточнить вопрос.")
124
+ else:
125
+ st.info("💡 Напиши вопрос, и я найду ответ в Википедии")