Update app.py
Browse files
app.py
CHANGED
@@ -11,6 +11,7 @@ import numpy as np
|
|
11 |
from urllib.parse import urlparse
|
12 |
import logging
|
13 |
from sklearn.preprocessing import normalize
|
|
|
14 |
|
15 |
# Настройка логирования
|
16 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
@@ -68,6 +69,9 @@ db_lock = threading.Lock()
|
|
68 |
# Размер пакета для обработки эмбеддингов
|
69 |
batch_size = 32
|
70 |
|
|
|
|
|
|
|
71 |
def get_db_connection():
|
72 |
"""Устанавливает соединение с базой данных."""
|
73 |
try:
|
@@ -195,6 +199,35 @@ def insert_embedding(conn, table_name, movie_id, embedding_crc32, string_crc32,
|
|
195 |
conn.rollback()
|
196 |
return False
|
197 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
198 |
def process_movies():
|
199 |
"""Обрабатывает фильмы, создавая для них эмбеддинги."""
|
200 |
global processing_complete
|
@@ -213,53 +246,31 @@ def process_movies():
|
|
213 |
for movie in movies_to_process:
|
214 |
movies_queue.put(movie)
|
215 |
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
220 |
|
221 |
-
|
222 |
-
while not movies_queue.empty():
|
223 |
-
if search_in_progress:
|
224 |
-
time.sleep(1)
|
225 |
-
continue
|
226 |
-
|
227 |
-
batch = []
|
228 |
-
while not movies_queue.empty() and len(batch) < batch_size:
|
229 |
-
try:
|
230 |
-
movie = movies_queue.get_nowait()
|
231 |
-
batch.append(movie)
|
232 |
-
except queue.Empty:
|
233 |
break
|
|
|
|
|
|
|
|
|
|
|
234 |
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
logging.info(f"Обработка пакета из {len(batch)} фильмов...")
|
239 |
-
|
240 |
-
for movie in batch:
|
241 |
-
embedding_string = f"Название: {movie['name']}\nГод: {movie['year']}\nЖанры: {movie['genresList']}\nОписание: {movie['description']}"
|
242 |
-
string_crc32 = calculate_crc32(embedding_string)
|
243 |
-
|
244 |
-
# Проверяем существующий эмбеддинг
|
245 |
-
existing_embedding = get_embedding_from_db(conn, embeddings_table, "string_crc32", string_crc32, model_name)
|
246 |
-
|
247 |
-
if existing_embedding is None:
|
248 |
-
embedding = encode_string(embedding_string)
|
249 |
-
embedding_crc32 = calculate_crc32(str(embedding.tolist()))
|
250 |
-
|
251 |
-
if insert_embedding(conn, embeddings_table, movie['id'], embedding_crc32, string_crc32, embedding):
|
252 |
-
logging.info(f"Сохранен эмбеддинг для '{movie['name']}'")
|
253 |
-
else:
|
254 |
-
logging.error(f"Ошибка сохранения эмбеддинга для '{movie['name']}'")
|
255 |
-
else:
|
256 |
-
logging.info(f"Эмбеддинг для '{movie['name']}' уже существует")
|
257 |
-
except Exception as e:
|
258 |
-
logging.error(f"Ошибка при обработке фильмов: {e}")
|
259 |
-
finally:
|
260 |
-
conn.close()
|
261 |
-
processing_complete = True
|
262 |
-
logging.info("Обработка фильмов завершена")
|
263 |
|
264 |
def get_movie_embeddings(conn):
|
265 |
"""Загружает все эмбеддинги фильмов из базы данных."""
|
@@ -278,7 +289,7 @@ def get_movie_embeddings(conn):
|
|
278 |
logging.error(f"Ошибка при загрузке эмбеддингов фильмов: {e}")
|
279 |
return movie_embeddings
|
280 |
|
281 |
-
def search_movies(query, top_k=
|
282 |
"""Выполняет поиск фильмов по запросу."""
|
283 |
global search_in_progress
|
284 |
search_in_progress = True
|
@@ -368,4 +379,4 @@ iface = gr.Interface(
|
|
368 |
)
|
369 |
|
370 |
# Запускаем интерфейс
|
371 |
-
iface.launch()
|
|
|
11 |
from urllib.parse import urlparse
|
12 |
import logging
|
13 |
from sklearn.preprocessing import normalize
|
14 |
+
from concurrent.futures import ThreadPoolExecutor
|
15 |
|
16 |
# Настройка логирования
|
17 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
|
|
69 |
# Размер пакета для обработки эмбеддингов
|
70 |
batch_size = 32
|
71 |
|
72 |
+
# Количество потоков для параллельной обработки
|
73 |
+
num_threads = 5
|
74 |
+
|
75 |
def get_db_connection():
|
76 |
"""Устанавливает соединение с базой данных."""
|
77 |
try:
|
|
|
199 |
conn.rollback()
|
200 |
return False
|
201 |
|
202 |
+
def process_batch(batch):
|
203 |
+
"""Обрабатывает пакет фильмов, создавая для них эмбеддинги."""
|
204 |
+
conn = get_db_connection()
|
205 |
+
if conn is None:
|
206 |
+
return
|
207 |
+
|
208 |
+
try:
|
209 |
+
for movie in batch:
|
210 |
+
embedding_string = f"Название: {movie['name']}\nГод: {movie['year']}\nЖанры: {movie['genresList']}\nОписание: {movie['description']}"
|
211 |
+
string_crc32 = calculate_crc32(embedding_string)
|
212 |
+
|
213 |
+
# Проверяем существующий эмбеддинг
|
214 |
+
existing_embedding = get_embedding_from_db(conn, embeddings_table, "string_crc32", string_crc32, model_name)
|
215 |
+
|
216 |
+
if existing_embedding is None:
|
217 |
+
embedding = encode_string(embedding_string)
|
218 |
+
embedding_crc32 = calculate_crc32(str(embedding.tolist()))
|
219 |
+
|
220 |
+
if insert_embedding(conn, embeddings_table, movie['id'], embedding_crc32, string_crc32, embedding):
|
221 |
+
logging.info(f"Сохранен эмбеддинг для '{movie['name']}'")
|
222 |
+
else:
|
223 |
+
logging.error(f"Ошибка сохранения эмбеддинга для '{movie['name']}'")
|
224 |
+
else:
|
225 |
+
logging.info(f"Эмбеддинг для '{movie['name']}' уже существует")
|
226 |
+
except Exception as e:
|
227 |
+
logging.error(f"Ошибка при обработке пакета фильмов: {e}")
|
228 |
+
finally:
|
229 |
+
conn.close()
|
230 |
+
|
231 |
def process_movies():
|
232 |
"""Обрабатывает фильмы, создавая для них эмбеддинги."""
|
233 |
global processing_complete
|
|
|
246 |
for movie in movies_to_process:
|
247 |
movies_queue.put(movie)
|
248 |
|
249 |
+
with ThreadPoolExecutor(max_workers=num_threads) as executor:
|
250 |
+
try:
|
251 |
+
while not movies_queue.empty():
|
252 |
+
if search_in_progress:
|
253 |
+
time.sleep(1)
|
254 |
+
continue
|
255 |
+
|
256 |
+
batch = []
|
257 |
+
while not movies_queue.empty() and len(batch) < batch_size:
|
258 |
+
try:
|
259 |
+
movie = movies_queue.get_nowait()
|
260 |
+
batch.append(movie)
|
261 |
+
except queue.Empty:
|
262 |
+
break
|
263 |
|
264 |
+
if not batch:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
265 |
break
|
266 |
+
|
267 |
+
executor.submit(process_batch, batch)
|
268 |
+
logging.info(f"Отправлен на обработку пакет из {len(batch)} фильмов.")
|
269 |
+
except Exception as e:
|
270 |
+
logging.error(f"Ошибка при обработке фильмов: {e}")
|
271 |
|
272 |
+
processing_complete = True
|
273 |
+
logging.info("Обработка фильмов завершена")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
274 |
|
275 |
def get_movie_embeddings(conn):
|
276 |
"""Загружает все эмбеддинги фильмов из базы данных."""
|
|
|
289 |
logging.error(f"Ошибка при загрузке эмбеддингов фильмов: {e}")
|
290 |
return movie_embeddings
|
291 |
|
292 |
+
def search_movies(query, top_k=20):
|
293 |
"""Выполняет поиск фильмов по запросу."""
|
294 |
global search_in_progress
|
295 |
search_in_progress = True
|
|
|
379 |
)
|
380 |
|
381 |
# Запускаем интерфейс
|
382 |
+
iface.launch()
|