Robocikowo>ROBOCIKOWO
Wyszukiwanie

HNSW

2016AktywnyOpublikowano: 20 maja 2026Aktualizacja: 20 maja 2026Opublikowany
HNSW (Hierarchical Navigable Small World) to algorytm ANN oparty na hierarchicznym grafie sąsiedztwa, zaproponowany przez Yury Malkova i Dmitry Yashunina (2016/2018). Jeden z najszybszych i najpopularniejszych indeksów wektorowych — domyślny lub główny wybór w Qdrant, Pinecone, Weaviate, pgvector, Elasticsearch, Milvus i FAISS.
Kluczowa innowacja
Wielowarstwowy graf bliskości typu „small world": górne warstwy zawierają rzadkie długodystansowe skróty dla szybkiej nawigacji globalnej, dolne — gęste lokalne sąsiedztwo dla precyzyjnego zbliżenia. Zapytanie schodzi z warstwy do warstwy w czasie logarytmicznym względem N.
Kategoria
Wyszukiwanie
Poziom abstrakcji
Building block
Poziom operacji
RetrievalDaneInferencja
Zastosowania
Wyszukiwanie semantyczne na 10⁶–10⁸ embeddingach (RAG, search)Domyślny indeks w wektorowych bazach: Qdrant, Pinecone, Weaviate, pgvector, MilvusWyszukiwanie podobnych obrazów / produktówRekomendacje w czasie rzeczywistym (sub-millisecond)Deduplikacja i wykrywanie niemal-duplikatówMobile / edge ANN (z mniejszym M)Hybrid search z BM25 + ANN (Elasticsearch, OpenSearch)

Jak działa

Budowa: (1) Dla każdego nowego wektora losuje się jego maksymalną warstwę l ~ Geometric(1/ln(M)) — większość ląduje w l=0, nieliczne sięgają wyżej. (2) Wektor jest wstawiany od warstwy l w dół. W każdej warstwie szuka się ef_construction kandydatów na sąsiadów (rozszerzone wyszukiwanie greedy), a następnie wybiera M (lub M_max0 dla warstwy 0) finalnych sąsiadów przez heurystykę pruningu — preferuje się punkty leżące w „różnych kierunkach" od wstawianego węzła, nie tylko najbliższe. (3) Krawędzie są dwukierunkowe; gdy sąsiad przekroczy M_max połączeń, jego krawędzie też są re-pruningowane. Wyszukiwanie: (a) start od entry pointu w najwyższej istniejącej warstwie, (b) greedy search w każdej warstwie aż do lokalnego minimum, ze stałym ef=1 w warstwach >0, (c) w warstwie 0 uruchamia się rozszerzony search z priority queue rozmiaru ef (search-time), (d) zwracane jest top-k z tej kolejki. Parametry M (typowo 16–48), ef_construction (100–500) i ef (50–500) sterują trade-offem build time / memory / recall / latency. Filtrowanie (np. WHERE category='X') zwykle realizowane jest jako filtered search z dynamicznym ef lub jako oddzielne grafy per kategoria.

Rozwiązany problem

Dokładne k-NN w przestrzeniach wysokowymiarowych ma koszt O(N · D) per zapytanie — niewykonalne dla miliona wektorów przy SLO milisekundowym. IVF i drzewa KD/ball-tree zawodzą w wysokich wymiarach z powodu „przekleństwa wymiarowości". HNSW rozwiązuje ten problem grafowo: zapewnia empirycznie czas O(log N) i recall ≥ 95% przy bardzo niskim opóźnieniu, dzięki czemu jest dziś faktycznym standardem do wyszukiwania wektorowego dla embeddingów AI w skali pojedynczego serwera.

Komponenty

Hierarchical layered graphStruktura indeksu

Warstwy 0..L: wyższe rzadkie (skróty long-range), niższe gęste. Liczba warstw wektora losowana geometrycznie z parametrem 1/ln(M).

Greedy beam search per layerAlgorytm zapytania

W warstwach >0: ef=1 (czysta nawigacja). W warstwie 0: priority queue rozmiaru ef (search-time) kontroluje recall/latency.

Diversity pruning heuristicWybór sąsiadów przy budowie

Zamiast brać po prostu M najbliższych kandydatów, HNSW preferuje kandydatów rozłożonych w różnych kierunkach (relative-neighborhood-graph style). Klucz do wysokiego recall.

Oficjalna

Adjacency lists (per layer)Reprezentacja krawędzi

Każdy węzeł ma w każdej warstwie listę co najwyżej M (M_max0 w warstwie 0) krawędzi. Bidirectional — wstawianie aktualizuje obie strony.

Implementacja

Pułapki implementacyjne
Za małe ef (search) → niski recallWysoka

Domyślne ef=10–32 daje recall <90% na realnych embeddingach AI (D≥384). To najczęstsze źródło „HNSW jest słaby" w blogach benchmarkowych.

Rozwiązanie:Tunować ef na walidacji do osiągnięcia target recall; ef można zmieniać per-zapytanie bez rebuildu.
Usuwanie / aktualizacje degradują grafWysoka

Klasyczny HNSW jest append-mostly. Usunięcia oznaczane są jako tombstones, a wstawianie nowych wersji nie zawsze przewiązuje krawędzi optymalnie — po wielu mutacjach recall spada i konieczny jest pełny rebuild.

Rozwiązanie:Planować okresowy rebuild; korzystać z wariantów wspierających "deletes with edge repair" (Qdrant, pgvector ≥ 0.6).
Filtered search — pułapka pustej kolejkiŚrednia

Filtry typu WHERE category='X' aplikowane post-hoc na top-ef wynikach mogą zwrócić mniej niż k pasujących wektorów. Trzeba dynamicznie zwiększać ef albo używać filtered-HNSW (predykat sprawdzany podczas traversal).

Rozwiązanie:Używać silników z natywnym filtered HNSW (Qdrant, Milvus, Weaviate); dla rzadkich kategorii rozważyć osobne grafy per kategoria.
RAM blow-up przy dużym M i wysokim DWysoka

HNSW trzyma pełne wektory + krawędzie w RAM. Dla 100M wektorów D=1536 (OpenAI embeddings) przy M=32 to ~700 GB RAM — szybko staje się ekonomicznie nieracjonalne.

Rozwiązanie:Dla N > ~50M rozważyć HNSW-PQ / HNSW-INT8 lub przeskoczyć na DiskANN / IVF-PQ.
Złe ułożenie entry pointu po rebuildzieNiska

Entry point HNSW to pojedynczy węzeł najwyższej warstwy. Po pełnym rebuildzie nieoptymalny entry point podbija liczbę kroków per zapytanie — czasem widoczne jako regresja latency bez zmiany recall.

Rozwiązanie:Monitorować średnią liczbę hops; niektóre implementacje wspierają warm-up i wybór entry pointu przez próbkowanie.

Ewolucja

Oryginalny paper · 2018 · IEEE TPAMI 2018 (preprint 2016) · Yury A. Malkov
Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs
Yury A. Malkov, Dmitry A. Yashunin
2014
Malkov et al. — NSW (Navigable Small World)

Poprzednik HNSW: jedna warstwa, idea grafu „small world" z krótkimi i długimi krawędziami. Już konkurencyjny, ale wolniejszy od HNSW.

2016
Malkov & Yashunin — preprint HNSW (arXiv:1603.09320)
Punkt przełomowy

Pierwsza publikacja HNSW: dodanie warstw hierarchicznych i heurystyki pruningu różnorodności. Przełom w jakości i prędkości ANN.

2017
nmslib — referencyjna implementacja C++

Open-source HNSW w nmslib (Non-Metric Space Library) — pierwsza szeroko używana implementacja, źródło dla wielu portów.

2018
Publikacja TPAMI; hnswlib jako standalone
Punkt przełomowy

Oficjalna publikacja w IEEE TPAMI. Yury Malkov udostępnia hnswlib — wydzieloną, szybką bibliotekę C++/Python wykorzystywaną do dziś jako referencja.

2022
HNSW jako domyślny indeks w wektorowych bazach

Qdrant, Pinecone, Weaviate, pgvector (≥ 0.5), Elasticsearch (8.0+), OpenSearch i Milvus — wszystkie wystawiają HNSW jako podstawowy lub jedyny indeks ANN.

2024
Warianty HNSW-PQ / HNSW-INT8 w głównym nurcie

Qdrant, Milvus, Lucene i pgvector dodają kompresję wektorów w grafie HNSW (PQ, scalar quantization, INT8) by zmniejszyć RAM bez utraty grafu.

Hiperparametry (konfigurowalne osie)

Max neighbors per node (M)Krytyczna

Maksymalna liczba sąsiadów per węzeł w warstwach >0 (w warstwie 0 zwykle M_max0 = 2·M). Większe M = wyższy recall, większe RAM, wolniejsza budowa.

8Małe RAM, niższy recall.
16Domyślne w wielu DB.
32–48High-recall, embeddingi AI.
ef_constructionWysoka

Rozmiar dynamicznej listy kandydatów podczas budowy grafu. Większe = lepsza jakość grafu (wyższy recall) kosztem dłuższej budowy.

100Domyślne, szybka budowa.
200–400Wyższy recall, wolniejsze indeksowanie.
ef (search-time)Krytyczna

Rozmiar priority queue podczas zapytania w warstwie 0. Główne pokrętło runtime recall vs latency — można zmieniać per-zapytanie bez przebudowy.

32Low-latency, recall ~85%.
128Typowy 95%+ recall.
500High-recall, kosztem latency.
M_max0 (layer 0 cap)Średnia

Maksymalna liczba sąsiadów w warstwie 0 (najgęstszej). Typowo 2·M; podbicie poprawia recall ale podwaja RAM warstwy 0.

2·MDomyślne z papieru.

Złożoność obliczeniowa

Złożoność czasowa: Query: O(log N) (empirical); Insert: O(log N · ef_construction · D). Złożoność przestrzenna: O(N · (D · 4B + M · 8B · L_avg)).

Wąskie gardło obliczeniowe

Distance computations during graph traversal

Większość czasu zapytania to dot products / L2 distance między query a wektorami napotkanych węzłów. Implementacje SIMD (AVX-512, NEON) są kluczowe dla wydajności.

Paradygmat wykonania

Tryb główny
sparse

Tylko niewielki podzbiór węzłów grafu jest odwiedzany per zapytanie (sparse traversal). To stoi w kontraście do PQ (dense scan) i bliżej DiskANN.

Wzorzec aktywacji
subset_active

Równoległość

Poziom równoległości
fully_parallel

Zapytania są niezależne — throughput skaluje się liniowo z liczbą rdzeni. Budowa grafu jest częściowo równoległa (lock per node przy aktualizacji krawędzi).

Zakres
inferenceacross_devices

Wymagania sprzętowe

Podstawowe

Wyszukiwanie HNSW dominują obliczenia dystansu (dot product / L2) na małych zestawach wektorów per krok. AVX2/AVX-512 zapewnia wymaganą przepustowość. GPU nie ma przewagi z powodu małych batchy per zapytanie i nieregularnego dostępu do pamięci.

Dobry fit

Implementacje HNSW działają wydajnie na ARM (Graviton, Apple Silicon, NEON) i x86. Kluczowa jest przepustowość pamięci i SIMD, nie konkretna ISA.

Ograniczony

Nieregularne odczyty grafu i mały batch per zapytanie nie mapują się dobrze na Tensor Cores zaprojektowane pod gęste GEMM. GPU może przyspieszyć budowę indeksu i ekstremalnie wysokoprzepustowe scenariusze, ale nie typowe pojedyncze zapytanie.