Dostosowywanie indeksów HNSW i skalowanie wyszukiwania wektorowego dla produkcji RAG
Dowiedz się, w jaki sposób parametry M i ef w HNSW wpływają na dokładność, opóźnienie i zużycie pamięci, jak ustawić je w Chroma oraz kiedy skalować bazę wektorową pionowo lub poprzez shardowanie.
Źródła: **15.**HNSW & Vector Database Tuning for Production RAG
Prototyp generacji wzbogaconej o wyszukiwanie (RAG) z kilkoma tysiącami wektorów odpowiada natychmiast niemal na każdym urządzeniu. Gdy zbiór rośnie do milionów elementów, opóźnienia i zużycie zasobów stają się dominującymi problemami, a konfiguracja indeksu staje się kwestią kluczową w środowisku produkcyjnym. Ten przewodnik omawia dwa najważniejsze parametry HNSW, sposób ich ustawienia w Chromie oraz kiedy dostrojenia już nie wystarczają i system musi zostać rozszerzony.
Dwa parametry HNSW, które kontrolują niemal wszystko
Nie musisz znać całej teorii grafów HNSW (Hierarchical Navigable Small World), aby ich dostosować. Indeks łączy każdy wektor z sąsiednimi wektorami na kilku warstwach, a zapytanie przemierza ten graf w kierunku najbliższych sąsiadów. Dwa parametry kształtują ten graf oraz to przemierzanie. Aby dowiedzieć się więcej, zapoznaj się z naszym wyjaśnieniem na temat jak działają bazy danych wektorowych, od embeddingów do wyszukiwania hybrydowego.
M: maksymalna liczba połączeń na węzeł
M określa maksymalną liczbę linków do sąsiadów, które każdy węzeł przechowuje w grafie.
- Niskie M: mniej linków, mniejszy indeks, mniej pamięci i szybsze przemierzanie grafu, ale niższy wskaźnik odzyskiwania wyników, ponieważ wyszukiwanie ma mniej dróg do dobrych kandydatów.
M jest ustalane przy tworzeniu indeksu, więc jego późniejsza zmiana oznacza konieczność ponownego utworzenia indeksu.
ef: intensywność poszukiwań
ef określa, ilu kandydatów indeks bierze pod uwagę podczas szukania najbliższych sąsiadów zapytania.
- Niskie ef: sprawdza się mniej kandydatów, więc odzyskiwanie informacji jest szybkie, ale mogą zostać pominięte istotne dokumenty, a dokładność spada.
- Wysokie ef: sprawdza się więcej kandydatów, więc odzyskiwanie informacji jest wolniejsze, ale zbiór wyników jest znacznie bliższy dokładnym najbliższym sąsiadom.
Wiele silników dzieli to na wartość określaną podczas konstruowania, która kontroluje stopień dokładności budowy grafu, oraz wartość określaną podczas wyszukiwania, którą zazwyczaj można zmienić bez konieczności ponownej budowy, co czyni ją najtańszym elementem do eksperymentowania.
Zrównoważenie dokładności, szybkości i pamięci
Dostrojenie HNSW polega na trójstronnym kompromisie pomiędzy dokładnością, szybkością a pamięcią. Te kombinacje stanowią rozsądne punkty wyjścia dla typowych etapów projektu, przy czym ef oznacza wartość określaną podczas wyszukiwania:
+----------------+----+-----+----------+
| Use Case | M | ef | Priority |
+----------------+----+-----+----------+
| Prototype | 16 | 40 | Speed |
| Production | 16 | 100 | Balanced |
| High accuracy | 32 | 200 | Accuracy |
+----------------+----+-----+----------+
Traktuj je jako punkty odniesienia do pomiarów: mierz stopień przywoływalności i opóźnienie dla reprezentatywnych zapytań przed i po każdej zmianie.
Ustawianie parametrów HNSW w Chroma
Każda baza danych wektorowych udostępnia te ustawienia w inny sposób. W Chromie można je przekazać jako metadane kolekcji podczas jej tworzenia. Poniższy przykład ustawia M na 16, ef w czasie konstrukcji na 100, a ef podczas wyszukiwania na 50:
#Chroma-HNSW Settings
collection=client.create_collection(
name='new_collection',
metadata={
'hnsw:M':16,
'hnsw:construction_ef': 100,
'hnsw:search_ef': 50
}
)
Ten styl kluczy metadanych może się różnić w nowszych wersjach Chromy, które oferują również dedykowany obiekt konfiguracyjny, dlatego sprawdź aktualną dokumentację dla swojej wersji. Ustaw M oraz ef podczas konstrukcji przed wprowadzaniem danych, ponieważ są one wbudowywane w graf.
Gdy dostrojenia już nie wystarczają
Nawet dobrze dostrojony indeks w końcu napotyka swoje ograniczenia. Gdy czas wyszukiwania regularnie przekracza 100 ms, częstą przyczyną jest to, że indeks nie mieści się już wygodnie w pamięci, a dalsze modyfikacje parametrów tego nie naprawią. Pomaga przybliżona ocena: surowa przechowalnia wektorów to liczba wektorów pomnożona przez ich wymiary, a następnie przez 4 bajty dla liczb zmiennoprzecinkowych o rozdzielczości 32 bitów; graf HNSW dodatkowo generuje nakładki, które rosną wraz z wartością M. W takiej sytuacji rozwiązaniem jest skalowanie, które występuje w dwóch formach.
Skalowanie pionowe
Dla zbiorów liczących około 5 do 10 milionów wektorów pierwszym krokiem jest zazwyczaj dodanie pamięci RAM lub mocy obliczeniowej CPU do istniejącego komputera. Przy wystarczającej ilości pamięci cały indeks mieści się w RAM, co przywraca szybkie wyszukiwanie i poprawia ogólną wydajność.
Skalowanie pionowe nie wymaga zmian w architekturze ani kodzie, ale pojedynczy komputer ma ograniczenia pamięciowe, a większe instancje szybko stają się drogie.
Skalowanie poziome
Po przekroczeniu około 10 milionów wektorów skalowanie poziome staje się praktyczną opcją. Zbiór jest dzielony na fragmenty, co oznacza, że dane są rozkładane między kilka instancji, a każdy fragment przechowuje i wyszukuje swoją część.
To eliminuje ograniczenia pojedynczego komputera. Cena takiego rozwiązania to złożoność: każde zapytanie jest kierowane do poszczególnych fragmentów, a ich częściowe wyniki muszą zostać połączone w jedną uporządkowaną listę, co zwiększa opóźnienia i obciążenie operacyjne.
Główne wnioski
Mwpływa na strukturę grafu: wyższe wartości zwiększają dokładność wyników i zużycie pamięci, a ich zmiana wymaga ponownego budowania struktury.efwpływa na proces wyszukiwania: zwiększenie wartości czasu wyszukiwania to najtańszy sposób na poświęcenie nieco opóźnienia dla lepszej dokładności wyników.
M 16 z parametrem wyszukiwania ef ustawionym na 100, a następnie przeprowadź testy na własnych zapytaniach.