Векторные БД vs Точность — часть 2

от автора

В первой части из тестов стало понятно, что с в векторном поиске с терминами что-то не так. И точность достаточно низкая для корректной работы RAG (retrieval augmentation generation)

В случае с толковым словарем Ожегова, может быть 2 типа вопросов:

  1. По содержимому или значению найти термин

  2. Найти термин, что он обозначает

Проблема во втором типе вопросов, когда на входе термин. Да, это не работает. И цифры это подтверждают. Теперь цель найти решение, для таких кейсов. А не наступать на мои грабли)

Одним из вариантов решения — использовать гибридный поиск, не все векторные БД его поддерживают:

  1. Chroma — в процессе реализации

  2. Pinecone — public preview — нету в Docker — запрос фичи

  3. Milvus — в процессе реализации

  4. Weaviate — поддерживает

  5. Qdrant — поддерживает

  6. Elasticsearch — поддерживает

  7. Opensearch — поддерживает

Так как Chroma, Pinecone, Milvus гибридный поиск пока отсутствует, то выбор пал на Weaviate.

Weaviate

Быстро пробежавшись по документации, вроде как все просто и понятно — надо брать в тест.

Поднимаем контейнер Weaviate с помощью docker-compose.yaml

version: '3.4' services:   weaviate:     command:     - --host     - 0.0.0.0     - --port     - '8080'     - --scheme     - http     image: cr.weaviate.io/semitechnologies/weaviate:1.24.11     ports:     - 8080:8080     - 50051:50051     volumes:     - weaviate_data:/var/lib/weaviate     restart: on-failure:0     environment:       QUERY_DEFAULTS_LIMIT: 25       AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'       PERSISTENCE_DATA_PATH: '/var/lib/weaviate'       #Hugginface usage       DEFAULT_VECTORIZER_MODULE: text2vec-huggingface       HUGGINGFACE_APIKEY: hf_****************************       #Dafault usage       #DEFAULT_VECTORIZER_MODULE: 'none'       ENABLE_MODULES: 'text2vec-cohere,text2vec-huggingface,text2vec-palm,text2vec-openai,generative-openai,generative-cohere,generative-palm,ref2vec-centroid,reranker-cohere,qna-openai'       CLUSTER_HOSTNAME: 'node1' volumes:   weaviate_data:

Ставим зависимости

%pip install -U sentence-transformers ipywidgets weaviate-client chardet charset-normalizer

Грузим датасет, также как и в первой части точь-в-точь.

Тянем список моделей, как в предыдущем тесте, чтобы потом сравнить

from weaviate.classes.config import VectorDistances models = [     "intfloat/multilingual-e5-large",     "sentence-transformers/paraphrase-multilingual-mpnet-base-v2",     "symanto/sn-xlm-roberta-base-snli-mnli-anli-xnli",     "cointegrated/LaBSE-en-ru",     "sentence-transformers/LaBSE" ]  distances = [     VectorDistances.L2_SQUARED,     VectorDistances.DOT,     VectorDistances.COSINE ]

Далее как и предыдущем тесте создаем коллекцию и грузим данные в БД согласно документации.

from tqdm import tqdm  from weaviate.classes.config import Configure, Property, DataType, Tokenization, VectorDistances  def create_collection(client, model_name, distance):          client.collections.create(         "title",         vectorizer_config=[             Configure.NamedVectors.text2vec_huggingface(                 name="title_vector",                 source_properties=["title"],                 model=model_name,                 vector_index_config=Configure.VectorIndex.hnsw(distance_metric=distance)             )         ]     )      collection = client.collections.get("title")          with collection.batch.dynamic() as batch:         for i, data in tqdm(dataset.iterrows()):             obj = {                 "title": data["title"]             }             batch.add_object(                 properties = obj             )      if len(collection.batch.failed_objects) > 0:          print(collection.batch.failed_objects)  def delete_collection(client):     client.collections.delete("title") 

Грузим для одной модели, чтобы проверить корректность кода

delete_collection(client) create_collection(client, "cointegrated/LaBSE-en-ru", VectorDistances.COSINE)

Вот тут произошло НО 🙁

1000it [00:04, 204.12it/s] [ErrorObject(message='vectorize target vector title_vector: update vector: failed with status: 429 error: Rate limit reached.  You reached free usage limit (reset hourly). Please subscribe to a plan at https://huggingface.co/pricing to use the API at this rate'...

Оказывается, что Weviate использует Huggingface не для того, чтобы скачать модель локально, как делают другие БД при создании коллекции. А использует модель на стороне инфраструктуры hugginface через API.

Схема работы Weaviate и huggingface

Схема работы Weaviate и huggingface

Можно использовать локально модели, но их нужно заворачивать в Docker образ и потом коннектить к Weaviate.

Решил не продолжать тест, так как он выбивается за рамки «по-быстрому» + хочется использовать локально модели. Поэтому переходим к Qdrant.

Qdrant

Поднимаем Docker-образ согласно документации

docker run -p 6333:6333 -v $PWD/qdrant_storage:/qdrant/storage qdrant/qdrant

Ставим нужные пакеты

%pip install -U qdrant-client

Грузим датасет, также как и в первой части точь-в-точь.

Тянем список моделей, как в предыдущем тесте + sentence-transformers/all-MiniLM-L6-v2 и sentence-transformers/paraphrase-multilingual-MiniLM-L12-v. Добавил моделей, так как FastEmbed из коробки ограничен список поддерживаемых моделей, который использует qdrant. Поэтому при создании коллекции, в некоторых будем ловить ошибку «Unsupported embedding model…»

Создаем коллекцию и грузим данные, согласно документации

from qdrant_client import QdrantClient, models as qdrant_models  client = QdrantClient(url="http://localhost:6333") COLLECTION_NAME="termins"  def create_collection(client, model_name):     client.set_model(model_name)     client.create_collection(         collection_name=COLLECTION_NAME,         vectors_config=client.get_fastembed_vector_params()     )     add_data()  def add_data():     ids = list(map(int, dataset.index.values.tolist()))      client.add(         collection_name=COLLECTION_NAME,         ids = ids, documents=dataset["title"].tolist(), batch_size=2, parallel=0     )   def delete_collection():     client.delete_collection(collection_name=COLLECTION_NAME)

В функция поиска ответа в БД особо не отличается от предыдущих. Но мы забираем с максимально высокой оценкой, так как в qdrant оценка, а не расстояние как в Chroma.

Запускаем тест ииии…

found

model_name

100

intfloat/multilingual-e5-large

100

sentence-transformers/paraphrase-multilingual-mpnet-base-v2

100

sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2

0

symanto/sn-xlm-roberta-base-snli-mnli-anli-xnli

100

sentence-transformers/all-MiniLM-L6-v2

0

cointegrated/LaBSE-en-ru

0

sentence-transformers/LaBSE

Получаем 100% попадание, там где 0 — это «Unsupported embedding model».

Интересно, а точно дело в гибридном поиске?

Давайте попробуем просто векторный поиск использовать в Qdrant

found

model_name

100

intfloat/multilingual-e5-large

100

sentence-transformers/paraphrase-multilingual-…

100

sentence-transformers/paraphrase-multilingual-…

100

sentence-transformers/all-MiniLM-L6-v2

Хм…и снова 100%

В этот момент меня начали одолевать сомнения, правильно ли я использовал Chroma, перепроверил код и запустил еще раз тест.

found

model_name

22

intfloat/multilingual-e5-large

23

sentence-transformers/paraphrase-multilingual-mpnet-base-v2

21

sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2

18

sentence-transformers/all-MiniLM-L6-v2

Исходный код

Заключение

Для RAG с моим кейсом и «по-быстрому» — используйте Qdrant и будет вам точность. Так как под капотом он работает фундаментально по-другому.

С другой стороны Chroma достаточно гибкая, но чтобы использовать нужно обладать определённой экспертизой и уметь её правильно варить.

Поэтому выбор векторной БД зависит от уровня экспертизы, условий и области применения. Каждая хороша по своему.

Which Vector Database Should You Use? Choosing the Best One for Your Needs | by Plaban Nayak | The AI Forum | Apr, 2024 | Medium


ссылка на оригинал статьи https://habr.com/ru/articles/817173/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *