Головна / Статті

Порівняльний аналіз п’яти вбудованих сховищ векторів: FAISS, Chroma, LanceDB, VectLite

П’ять вбудованих векторних баз даних, протестованих для локального RAG: FAISS, Chroma, LanceDB, VectLite та NumPy — порівняння за точністю, затримкою, фільтрами та проблемою «холодного старту».

Видавець: REACTAPP.TOP8 хв читання1791 слів

Джерела: I Benchmarked 5 Vector Databases for a Local RAG. Only One Actually Surprised Me.

Більшість порівнянь „найкращих баз даних векторів“ схожі на перефразовані власні сторінки-вхідні для постачальників: Pinecone — швидкий, Qdrant — надійний, Chroma — простий, усі перемагають. Цей огляд ґрунтується на вузькішій потребі. Жодних кластерів, жодного Docker, жодних відкритих портів, жодних планів з управлінням. Лише вбудована база даних векторів, яка складається з одного локального файлу, команди pip install та трьох рядків коду на Python. Ось домашній тестувальний звіт для п’яти двигунів саме для цієї мети.

Цифри

Набір даних містив 5 000 векторів з 384 вимірами; він оброблявся 50 разів за допомогою косинусової схожості. Усе працювало на macOS (x86_64) з Python 3.12.8, з використанням стандартних налаштувань кожного двигуна.

Двигун Швидкість введення (векторів/с) Швидкість пошуку p95 Рівень відтворення@10 Швидкість фільтрації p95 Рівень відтворення після фільтрації@10
FAISS 743,099 0.65 мс 1.000 n/a без фільтрації
NumPy exact 2,412,231 2,59 мс 1,000 9,25 мс 1,000
Chroma 2,011 3,14 мс 0,840 18,76 мс 1,000
VectLite 0,10,0 154 5,71 мс 0,966 10,28 мс 0,966
LanceDB 20,120 12,20 мс 1,000 14,11 мс 1,000

Через десять секунд: FAISS є найшвидшим, хоча його важко вважати базою даних. Chroma — найпростіший варіант для початку, але його стандартний рівень відтворення даних у 84% є проблемою, яку багато хто ігнорує. VectLite досягає рівня відтворення 96,6% у вбудованому режимі без налаштувань, що стало сюрпризом. LanceDB прагне ідеального рівня відтворення, але за це платить затримкою. NumPy є лише арбітром, а не конкурентом.

Чому «найшвидший» — це неправильний критерій ранжування

Ринок векторних БД — це справжня маркетингова битва. Кожен постачальник публікує результати тестів, у яких йому вдається перемогти, статті з порівнянням повторюють ці цифри без контексту, а всі зосереджуються на затримці. Сама по собі затримка вводить в оману. Відповідь протягом пів мілісекунди з неправильними результатами гірша, ніж 5 мс на отримання правильних даних. Саме це вимірює показник відтворення, і саме тому серйозні набори тестів, такі як ANN-Benchmarks (https://ann-benchmarks.com/), показують відтворення порівняно з пропускною здатністю.

Тож цей тест вимірює обидва показники одночасно: з одного боку — затримку p50, p95 та p99 та кількість запитів на секунду, а з іншого — показник відтворення@10 у порівнянні з точним пошуком за допомогою косинуса у звичайному NumPy.

Що тестувалося, а що ні

Цей проект — це невеликий пакет Python під назвою vectlite-benchmark-lab. Кожен двигун реалізує спільний інтерфейс VectorStore, і запускач по черзі викликає їх. Він охоплює:

  • Пакетну обробку даних
  • Пошук k-NN із вимірюванням точності
  • Фільтрацію метаданих за критерієм точного збігу за допомогою tenant_id
  • Час початку роботи
  • Резервне копіювання та портативність
  • Експорт у форматах CSV, JSON та графіки Matplotlib

А що він не враховує, про що зазначено заздалегідь: жодної дистрибуйованої чи багатоузлової конфігурації, не більше 5 000 векторів у цьому турі, жодної налаштування індексу, а також жодних інструментів типу Qdrant чи pgvector, оскільки вони потребують працюючого сервера, а метою був чисто локальний запуск. Цей останній вибір є навмисним. Перше корисне запитання — це не те, хто переможе після двох тижнів налаштувань, а те, як поводиться двигун після його встановлення без будь-яких змін.

Метод

«Ground truth» — це пошук за косинусом з використанням brute-force у NumPy. Рівень відтворення двигуна — це частка справжніх сусідів, які він повертає, у середньому за всі запити. Конфігурація для виконання:

vectlite      : 0.10.0
vectors       : 5,000 (synthetic, normalized)
dimensions    : 384
queries       : 50
top_k         : 10
metric        : cosine
filter        : tenant_id (exact-match)
warmup        : 5 queries discarded
hardware      : macOS x86_64, Python 3.12.8

Щоб відтворити його на вашому пристрої, виконайте повну команду:

PYTHONPATH=src python -m vectlite_benchmark_lab run \
  --stores vectlite,faiss,chroma,lancedb,numpy_exact \
  --vectors 5000 --dimensions 384 --queries 50 \
  --top-k 10 --batch-size 500 \
  --output-dir results/vectlite-0.10.0 \
  --data-dir data/vectlite-0.10.0

Потім порівняйте свої результати з цими та подивіться на відмінності.

FAISS: верхня межа швидкості

FAISS перемагає у всіх показниках затримки: 0,65 мс p95 із ідеальним рівнем відтворення даних, що є приблизно тим, чого можна очікувати від бібліотеки на C++, оптимізованої саме для цього протягом десятиліття. Але це не база даних. У неї немає вбудованого фільтрування метаданих, немає вбудованої функції зберігання даних та немає портативних засобів резервного копіювання. Її можна обгорнути шаром, який додасть ці функції, і так і роблять, проте без додаткових налаштувань вона більше схожа на математичну бібліотеку, ніж на інструмент, який можна надавати клієнтам. Порівнювати її з Chroma — це як порівнювати двигун F1 з Toyota: один швидший на трасі, інший доставляє продукти додому. Цей опис залишається у таблиці як посилання. Якщо вам потрібен лише простий пошук векторів, це очевидний вибір.

Chroma: простий початок, стежте за рівнем відтворення даних

Chroma є стандартним вибором для прототипів RAG, і це зумовлено досвідом розробника під час роботи з нею. Встановіть chromadb, напишіть п’ять рядків коду — і документи вже індексуються.

Проблема полягає у рівні відтворення даних. За замовчуванням, без застосування фільтрів, Chroma знаходить лише 84% справжніх сусідніх документів, що означає, що приблизно один із шести очікуваних результатів так і не з’являється. Це прийнятно для прототипу. Однак у продакшн-системах RAG, де якість пошуку впливає на відповідь моделі, це є прихованою втратою релевантності, яку API ніколи не виявляє. Коригування налаштувань HNSW допомагає подолати більшу частину цього розриву, за умови, що ви усвідомлюєте необхідність цього. За допомогою фільтрації рівень відтворення досягає 100%, але затримка p95 зростає до 18,76 мс, що значно повільніше, ніж у інших варіантів для однакової роботи. Висновок: чудово з першого дня та все ще гарно через тридцять днів, за умови налаштувань перед впровадженням у продакшн.

VectLite: сюрприз

У версії 0.10.0 при стандартних налаштуваннях рівень відтворення даних становить 96,6%, що є найвищим серед усіх вбудованих двигунів. Час виконання простого пошуку за показником p95 становить 5,71 мс, що знаходиться на середньому рівні (Chroma 3,14, LanceDB 12,20). При фільтрації даних час виконання за показником p95 становить 10,28 мс, на відміну від 18,76 мс у Chroma, тобто тут він майже вдвічі швидший.

Видно прогрес з моменту перших випусків. Порівняно з версією v0,1.x швидкість обробки даних зросла з 47 до 154 векторів/с (приблизно в 3,3 рази швидше), рівень відтворення даних підвищився з 0,948 до 0,966, а час виконання фільтрації за показником p95 знизився з 18,6 мс до 10,3 мс, що на 45% менше.

Слабкою стороною є швидкість обробки даних. 154 вектори/с — це повільно порівняно з 2000 та більше векторів/с у Chroma та дуже повільно порівняно з LanceDB. Для кількох тисяч документів, індексованих один раз, це не має значення. Але для мільйона векторів це означає довге очікування, тож це, ймовірно, наступна проблема, яку потрібно вирішити. Проте це був єдиний двигун у групі, чиї показники не потребували жодних виправдань.

LanceDB: ідеальна точність, повільний пошук

LanceDB досягає 100% точності та обробляє 20 120 векторів на секунду, що на папері виглядає вражаюче. Однак ціною є затримка пошуку: 12,20 мс (p95) — це найгірший показник серед п’яти. Для пакетної обробки тисяч запитів протягом ночі це не має значення. Але для інтерактивного інструменту, де людина чекає біля клавіатури, це стає значущим фактором. Підходить для пакетної обробки та аналітики, але трохи повільний для інтерактивного використання.

NumPy: арбітр

Пошук за допомогою методу косинуса над повною матрицею за визначенням забезпечує ідеальну точність, з прийнятною затримкою до кількох десятків тисяч векторів, після чого продуктивність різко падає. Це не продукт, а арбітр, за яким оцінюються всі інші двигуни.

Який вибрати

Бенчмарк не визначає переможця — він виявляє компроміси. Орієнтовне співвідношення залежно від сценарію використання:

  • Швидкий прототип RAG: Chroma – завдяки двомінутній налаштуванню та великій екосистемі
  • Вбудована пам’ять ШІ: VectLite – для найкращого стандартного відтворення даних та портативного формату файлів
  • Локальний пакетний процес: LanceDB – для ідеального відтворення даних та швидкого їх завантаження
  • Чиста сітка нейронних мереж без фільтрації: FAISS – для неперевершеної затримки обробки
  • Розподілена система для продакшну: Qdrant або Milvus – інша категорія, яка тут не тестувалась

Початок роботи та резервне копіювання

Два показники, які більшість тестів ігнорує. Час запуску – час, необхідний для знову відкриття бази даних після перезавантаження: FAISS – 0,001 мс, LanceDB – 2 мс, Chroma – 5 мс, VectLite – 3 059 мс. VectLite сильно поступається у часі зновувідкриття. Це не має значення для процесу, що працює тривалий час, але для безсерверної функції чи інструменту командного рядка, який запускається за потребою, трисекундний час початку роботи є серйозною проблемою та, ймовірно, першою річчю, яку потрібно виправити.

Резервне копіювання: VectLite створює портативний файл розміром 19 МБ за 54 мс. Копіювання, версіонування та розгортання — це просто обробка файлів. Саме ця „вбудована“ функція забезпечує ефективність, та сама властивість, яка допомогла SQLite існувати протягом двох десятиліть.

Обмеження цього тестування

Кожен тест-кейс потребує уточнень. Ось п’ять з них:

  1. 5 000 векторів — це невелика кількість, а поведінка змінюється при 100 тис. та більше.
  2. Використовувалися лише стандартні налаштування, причому параметри Chroma та VectLite, ймовірно, можна налаштувати ще краще.
  3. У тесті не брали участі жодні серверні движки: Qdrant, Milvus, Weaviate та pgvector виключені.
  4. Це один екземпляр тесту, без інтервалів довіри та повторень.
  5. Тест виконувався на одній машині, тож інше обладнання може дати інші результати.

Код є відкритим, а результати можна відтворити, тому виявлена схильність чи баг варто задокументувати.

Наступні кроки та висновки

Цей тест є лише відправною точкою, а не остаточним вердиктом. Короткий список для наступного етапу: вектор довжиною 100 тис., тест у 768 вимірах для всіх двигунів; тест у стилі RAG з використанням корпусів Markdown та PDF із запитами, написаними людьми; налаштована точність відтворення даних, щоб двигуни змагалися при порівнянній точності; скорочений час запуску VectLite; а також повторні тести з інтервалами довіри.

Пошук „найкращої бази даних векторів“ закінчується без універсальної відповіді, адже це залежить від того, як ви збалансовуєте точність повернення даних з часом відгуку, процесом вставки та часом запуску. Найбільше привернуло увагу не якийсь явний лідер, а те, що кожен інструмент має свою особливість. FAISS — це інструмент для швидкості, який видає себе за базу даних. Chroma — це простий інструмент для початку роботи, який потребує налаштувань перед використанням у продакшені. LanceDB — це перфекціоніст, якому байдужа повільність. NumPy — це неупереджений суддя, який не може масштабуватися. VectLite — це той інструмент, який тихо досягає цілі щодо точності повернення даних без жодних компромісів.

Для локального використання, інструменту командного рядка чи системи RAG, орієнтованої на роботу офлайн на ноутбуці, VectLite є переконливим варіантом: SQLite зробив локальні реляційні дані нудними та портативними, а VectLite прагне виконувати ту саму функцію за допомогою штучного інтелекту. Це означає файл розміром 19 МБ, який відповідає на запити приблизно за 6 мс.

Посилання: ANN-Benchmarks за адресою https://ann-benchmarks.com/, інформація про тестування від Qdrant за адресою https://qdrant.tech/benchmarks/, FAISS за адресою https://github.com/facebookresearch/faiss, документація Chroma за адресою https://docs.trychroma.com/ та LanceDB за адресою https://lancedb.github.io/lancedb/.