Spaces:
Sleeping
Sleeping
import logging | |
import faiss | |
import numpy as np | |
from common.constants import DO_NORMALIZATION | |
from components.embedding_extraction import EmbeddingExtractor | |
logger = logging.getLogger(__name__) | |
class FaissVectorSearch: | |
def __init__( | |
self, | |
model: EmbeddingExtractor, | |
ids_to_embeddings: dict[str, np.ndarray], | |
): | |
self.model = model | |
self.index_to_id = {i: id_ for i, id_ in enumerate(ids_to_embeddings.keys())} | |
self.__create_index(ids_to_embeddings) | |
def __create_index(self, ids_to_embeddings: dict[str, np.ndarray]): | |
"""Создает индекс для векторного поиска.""" | |
if len(ids_to_embeddings) == 0: | |
self.index = None | |
return | |
embeddings = np.array(list(ids_to_embeddings.values())) | |
dim = embeddings.shape[1] | |
self.index = faiss.IndexFlatIP(dim) | |
self.index.add(embeddings) | |
def search_vectors( | |
self, | |
query: str, | |
max_entities: int = 100, | |
) -> tuple[np.ndarray, np.ndarray, np.ndarray]: | |
""" | |
Поиск векторов в индексе. | |
Args: | |
query: Строка, запрос для поиска. | |
max_entities: Максимальное количество найденных сущностей. | |
Returns: | |
tuple[np.ndarray, np.ndarray, np.ndarray]: Кортеж из трех массивов: | |
- np.ndarray: Вектор запроса (1, embedding_size) | |
- np.ndarray: Оценки косинусного сходства (чем больше, тем лучше) | |
- np.ndarray: Идентификаторы найденных векторов | |
""" | |
logger.info(f"Searching vectors in index for query: {query}") | |
if self.index is None: | |
return (np.array([]), np.array([]), np.array([])) | |
query_embeds = self.model.query_embed_extraction(query, DO_NORMALIZATION) | |
similarities, indexes = self.index.search(query_embeds, max_entities) | |
ids = [self.index_to_id[index] for index in indexes[0]] | |
return query_embeds, similarities[0], np.array(ids) | |