Update app.py
Browse files
app.py
CHANGED
|
@@ -5,6 +5,7 @@ import os
|
|
| 5 |
import time
|
| 6 |
import threading
|
| 7 |
import queue
|
|
|
|
| 8 |
|
| 9 |
# Загружаем модель
|
| 10 |
model_name = "HIT-TMG/KaLM-embedding-multilingual-mini-instruct-v1"
|
|
@@ -53,6 +54,9 @@ search_in_progress = False
|
|
| 53 |
# Блокировка для доступа к movie_embeddings
|
| 54 |
movie_embeddings_lock = threading.Lock()
|
| 55 |
|
|
|
|
|
|
|
|
|
|
| 56 |
def encode_string(text):
|
| 57 |
"""Кодирует строку в эмбеддинг."""
|
| 58 |
return model.encode(text, convert_to_tensor=True)
|
|
@@ -67,28 +71,35 @@ def process_movies():
|
|
| 67 |
time.sleep(1) # Ждем, пока поиск не завершится
|
| 68 |
continue
|
| 69 |
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
print("Очередь фильмов пуста.")
|
| 74 |
processing_complete = True
|
| 75 |
break
|
| 76 |
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
|
|
|
| 81 |
|
| 82 |
-
print(f"Созда
|
| 83 |
-
|
| 84 |
-
embedding = encode_string(embedding_string).tolist()
|
| 85 |
|
| 86 |
with movie_embeddings_lock:
|
| 87 |
-
|
| 88 |
-
|
|
|
|
| 89 |
with open(embeddings_file, "w", encoding="utf-8") as f:
|
| 90 |
json.dump(movie_embeddings, f, ensure_ascii=False, indent=4)
|
| 91 |
-
print(f"Эмбеддинг для фильм
|
| 92 |
|
| 93 |
print("Обработка фильмов завершена.")
|
| 94 |
|
|
@@ -137,21 +148,20 @@ def search_movies(query, top_k=3):
|
|
| 137 |
search_in_progress = False
|
| 138 |
return "<p>Пока что нет обработанных фильмов. Попробуйте позже.</p>"
|
| 139 |
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
print(f"Начало вычисления косинусного сходства: {time.strftime('%Y-%m-%d %H:%M:%S')}")
|
| 145 |
-
similarity_scores = []
|
| 146 |
-
for title, embedding in current_movie_embeddings.items():
|
| 147 |
-
similarity = util.pytorch_cos_sim(query_embedding_tensor, encode_string(movie_descriptions[title]))[0][0].item()
|
| 148 |
-
similarity_scores.append((title, similarity))
|
| 149 |
-
print(f"Окончание вычисления косинусного сходства: {time.strftime('%Y-%m-%d %H:%M:%S')}")
|
| 150 |
|
| 151 |
-
|
|
|
|
|
|
|
|
|
|
| 152 |
|
| 153 |
results_html = ""
|
| 154 |
-
for
|
|
|
|
|
|
|
|
|
|
| 155 |
for movie in movies_data:
|
| 156 |
if movie["name"] == title:
|
| 157 |
description = movie["description"]
|
|
|
|
| 5 |
import time
|
| 6 |
import threading
|
| 7 |
import queue
|
| 8 |
+
import torch
|
| 9 |
|
| 10 |
# Загружаем модель
|
| 11 |
model_name = "HIT-TMG/KaLM-embedding-multilingual-mini-instruct-v1"
|
|
|
|
| 54 |
# Блокировка для доступа к movie_embeddings
|
| 55 |
movie_embeddings_lock = threading.Lock()
|
| 56 |
|
| 57 |
+
# Размер пакета для обработки эмбеддингов
|
| 58 |
+
batch_size = 16 # Подберите оптимальный размер
|
| 59 |
+
|
| 60 |
def encode_string(text):
|
| 61 |
"""Кодирует строку в эмбеддинг."""
|
| 62 |
return model.encode(text, convert_to_tensor=True)
|
|
|
|
| 71 |
time.sleep(1) # Ждем, пока поиск не завершится
|
| 72 |
continue
|
| 73 |
|
| 74 |
+
batch = []
|
| 75 |
+
while not movies_queue.empty() and len(batch) < batch_size:
|
| 76 |
+
try:
|
| 77 |
+
movie = movies_queue.get(timeout=1)
|
| 78 |
+
batch.append(movie)
|
| 79 |
+
except queue.Empty:
|
| 80 |
+
break
|
| 81 |
+
|
| 82 |
+
if not batch:
|
| 83 |
print("Очередь фильмов пуста.")
|
| 84 |
processing_complete = True
|
| 85 |
break
|
| 86 |
|
| 87 |
+
titles = [movie["name"] for movie in batch]
|
| 88 |
+
embedding_strings = [
|
| 89 |
+
f"Название: {movie['name']}\nГод: {movie['year']}\nЖанры: {movie['genresList']}\nОписание: {movie['description']}"
|
| 90 |
+
for movie in batch
|
| 91 |
+
]
|
| 92 |
|
| 93 |
+
print(f"Создаются эмбеддинги для фильмов: {', '.join(titles)}...")
|
| 94 |
+
embeddings = model.encode(embedding_strings, convert_to_tensor=True, batch_size=batch_size).tolist()
|
|
|
|
| 95 |
|
| 96 |
with movie_embeddings_lock:
|
| 97 |
+
for title, embedding in zip(titles, embeddings):
|
| 98 |
+
movie_embeddings[title] = embedding
|
| 99 |
+
# Сохраняем эмбеддинги в файл после обработки каждого пакета
|
| 100 |
with open(embeddings_file, "w", encoding="utf-8") as f:
|
| 101 |
json.dump(movie_embeddings, f, ensure_ascii=False, indent=4)
|
| 102 |
+
print(f"Эмбеддинги для фильмов: {', '.join(titles)} созданы и сохранены.")
|
| 103 |
|
| 104 |
print("Обработка фильмов завершена.")
|
| 105 |
|
|
|
|
| 148 |
search_in_progress = False
|
| 149 |
return "<p>Пока что нет обработанных фильмов. Попробуйте позже.</p>"
|
| 150 |
|
| 151 |
+
# Преобразуем эмбеддинги фильмов в тензор
|
| 152 |
+
movie_titles = list(current_movie_embeddings.keys())
|
| 153 |
+
movie_embeddings_tensor = torch.tensor(list(current_movie_embeddings.values()))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
|
| 155 |
+
print(f"Начало поиска похожих фильмов: {time.strftime('%Y-%m-%d %H:%M:%S')}")
|
| 156 |
+
# Используем util.semantic_search для поиска похожих фильмов
|
| 157 |
+
hits = util.semantic_search(query_embedding_tensor, movie_embeddings_tensor, top_k=top_k)[0]
|
| 158 |
+
print(f"Окончание поиска похожих фильмов: {time.strftime('%Y-%m-%d %H:%M:%S')}")
|
| 159 |
|
| 160 |
results_html = ""
|
| 161 |
+
for hit in hits:
|
| 162 |
+
title = movie_titles[hit['corpus_id']]
|
| 163 |
+
score = hit['score']
|
| 164 |
+
# Ищем полное описание фильма в исходных данных
|
| 165 |
for movie in movies_data:
|
| 166 |
if movie["name"] == title:
|
| 167 |
description = movie["description"]
|