Strona główna / Artykuły

turbovec: Kompresuj embeddingi RAG 16x za pomocą TurboQuant w Rust

TurboVec przenosi TurboQuant od Google do języka Rust i zmniejsza rozmiar indeksów embeddingów RAG 16 razy bez konieczności szkolenia. Gdzie przewyższa FAISS oraz kiedy inny narzędzie jest lepsze.

Wydawca: REACTAPP.TOP10 min czytania2219 słów

Źródła: turbovec for RAG: A Practical Guide to Faster, Smaller Vector Search

Weźmy pipeline wyszukiwania w rzeczywistym użyciu: dziesięć milionów dokumentów, z których każdy ma wbudowany model OpenAI text-embedding-3-small o 1536 wymiarach i jest przechowywany w formacie float32. Zanim dodany zostanie choćby jeden bajt metadanych, same wektory zajmują 31 GB. Przy takiej wielkości pytanie „gdzie to ma działać?” przestaje być błahym zapytaniem – oznacza to potężną maszynę chmurową wymagającą dużej ilości pamięci, prawdopodobnie zarządzaną przez kogoś innego, wraz ze wszystkimi problemami związanymi z prywatnością i obsługą takiego rozwiązania.

Gdy te same dane przetworzymy za pomocą turbovec przy użyciu 2 bitów na wymiar, ich rozmiar spada do około 4 GB, co mieści się bez problemu w pamięci RAM laptopa. W dalszej części tego tekstu wyjaśniono, dlaczego to działa, w jakich przypadkach jest to najlepszy wybór, a gdzie inne narzędzia sprawdzą się lepiej.

Czym jest turbovec

turbovec to wektorowy indeks w języku Rust z interfejsami w Pythonie, licencjonowany na zasadach MIT; w momencie pisania tego tekstu miał około 950 gwiazdek na GitHubie. Implementuje TurboQuant – algorytm kwantyzacji wektorowej opracowany przez badaczy z Google Research i NYU, który został przyjęty na konferencji ICLR 2026.

Warto znać jeden szczegół: Google nigdy nie opublikował kodu źródłowego swojego algorytmu, więc społeczność wzięła to na siebie. Projekt RyanCodrai/turbovec skupia się na wyszukiwaniu wektorowym, które jest zastosowaniem służącym do odzyskiwania informacji, natomiast oddzielny projekt hackimov/turboquant-kv stosuje tę samą koncepcję do kompresowania pamięci KV modeli językowych. Obie to niezależne inicjatywy otwartego oprogramowania.

Innymi słowy, użycie turbovec oznacza korzystanie z implementacji algorytmu z Google Research stworzonej przez społeczność, a w testach używanych przez sam zespół FAISS przewyższa on FAISS od Meta, który od dawna jest standardem w wyszukiwaniu wektorowym w pamięci operacyjnej.

Jak działa algorytm

Gdy już go zobaczysz, okazuje się, że metoda jest zaskakująco prosta. Działa w czterech krokach.

1. Oddzielenie długości od kierunku

Każdy wektor embedding ma wartość bezwzględną (jego normę L2) oraz kierunek. Wartość bezwzględną wyodrębnia się i przechowuje jako pojedynczą liczbę zmiennoprzecinkową na każdy wektor, a to, co pozostaje, to kierunek o długości jednostkowej na sferze wysokowymiarowej. Może to wydawać się błahe, ale wszystko, co następuje później, zależy od tego, ponieważ wektory znajdujące się na powierzchni sfery można obsługiwać za pomocą geometrii.

2. Losowe obrotowanie

Następnie każdy wektor jest mnożony przez tę samą losową macierz ortogonalną, wygenerowaną raz na podstawie rozkładu QR macierzy gaussowskiej. To krok, który przy pierwszym przeczytaniu wydaje się czarną magią.

Intuicja jest taka: w wysokich wymiarach losowa rotacja sprawia, że rozkład każdej współrzędnej staje się przewidywalny. Po rotacji każda współrzędna każdego wektora podąża za znanym, ściśle skoncentrowanym rozkładem Beta, który wraz ze wzrostem liczby wymiarów zbliża się do rozkładu gaussowskiego. Rozkład ten jest taki sam niezależnie od wejścia – dokumenty prawnicze, recenzje produktów i literatura medyczna statystycznie wyglądają podobnie, więc schemat nie zależy od danych. Matematycy nazywają to koncentracją miary na sferze i to wyjaśnia, dlaczego nie jest potrzebny żaden etap szkolenia: rotacja wykonuje pracę, którą w przeciwnym razie wykonałby przeszkolony kodownik.

3. Wybierz najlepsze grupy

Znajomość rozkładu, którym kieruje się każda współrzędna, oznacza, że najlepszy sposób grupowania wartości można obliczyć z góry. Kwantyzacja dwubitowa daje cztery grupy na współrzędną, a kwantyzacja czterobitowa – szesnaście. Ten proces nazywa się kwantyzacją skalarną Lloyd-Max i odpowiada na proste pytanie: przy znanym rozkładzie, gdzie powinny przebiegać linie podziału, aby średni błąd zaokrąglania był jak najniższy? Gdy rozkład jest znany, odpowiedź ma postać wzoru zamkniętego. A ponieważ rozkład po rotacji jest identyczny dla wszystkich wektorów, grupy wynikają z matematyki, a nie z danych.

4. Pakowanie bitów

Każda współrzędna jest teraz małą liczbą całkowitą: od 0 do 3 przy kwantyzacji dwubitowej lub od 0 do 15 przy kwantyzacji czterobitowej. Po szczelnym spakowaniu wektor 1536-wymiarowy, który zajmował 6 144 bajtów w formacie float32, potrzebuje 384 bajtów przy kwantyzacji dwubitowej lub 768 bajtów przy kwantyzacji czterobitowej. To oznacza kompresję 16-krotną i 8-krotną.

Szukanie bez rozpakowywania

Zapytania nigdy nie dekompresują przechowywanych danych. Zapytanie jest najpierw umieszczane w tym samym obszarze, a następnie porównywane bezpośrednio z zakodowanymi danymi przy użyciu tabel wyszukiwania przygotowanych z góry. Pętla wewnętrzna opiera się na instrukcjach SIMD – dla ARM używa się NEON, dla nowszych procesorów x86 – AVX-512BW, a jako alternatywa AVX2.

Właśnie tutaj biblioteka, w odróżnieniu od algorytmu, pokazuje swoją wartość. Jej ręcznie napisane jądra SIMD przewyższają szybkość FastScan z FAISS o 12 do 20 procent na procesorach ARM, a na procesorach x86 dorównują im lub je przewyższają.

Metoda opiera się również na wyniku teoretycznym. Artykuł o TurboQuant dowodzi, że stopień zniekształcenia pozostaje w granicach około 2,7 raza mniejszych niż dolna granica określona przez teorię informacji – limit szybkości zniekształcenia Shannona. Mówiąc prościej: teoria informacji określa, jak mocno można sprężyć dane, zanim dojdzie do utraty informacji, a TurboQuant osiąga poziom 2,7 raza bliższy tej granicy bez żadnego szkolenia. Nikt nie może osiągnąć znacznie lepszych wyników przy danym budżecie bitowym, a artykuł potwierdza to formalnym dowodem.

Trzy przypadki, w których metoda się sprawdza

Pamięć o odpowiedniej pojemności

Wracając do początkowych danych: 31 GB typu float32 w porównaniu z 4 GB przy użyciu turbovec z kodowaniem 2-bitowym. Taka mała ilość pamięci zmienia możliwości.

  • Może znajdować się obok aplikacji na tym samym serwerze, bez osobnej instancji bazy danych wektorowej.
  • Rozwijający mogą uruchamiać ją na laptopach do lokalnych testów.
  • Taniej dostępne poziomy pamięci w instancjach chmurowych stają się wykonalne, co znacząco obniża koszty.
  • Cały indeks pozostaje w pamięci RAM, bez zapisu na dysku i bez dzielenia na fragmenty między węzłami.

Dla zbiorów o zakresie wektorowym od 100 tysięcy do 100 milionów, które obejmują większość baz wiedzy, stron dokumentacyjnych, archiwów wsparcia i katalogów produktów, to właśnie jest różnica między koniecznością projektowania z myślą o indeksie wektorowym a traktowaniem go jak zwykłego obiektu Pythona.

Prywatność i rozwiązania izolowane

Procesy odzyskiwania informacji niosą ze sobą dość poważny problem prywatności. Ilustrują to dwa ataki:

  • BadRAG osiąga stopę skuteczności 98,2%, trując zaledwie 0,04% korpusu starannie przygotowanymi dokumentami adwersarialnymi.
  • Vec2Text odzyskuje krótkie oryginalne teksty z ich embeddingów, trafiając dokładnie w 92% przypadków.

Embeddingi nie posiadają żadnej ochrony kryptograficznej, więc każdy, kto ma dostęp odczytu do magazynu wektorów, może odzyskać to, co zostało tam umieszczone. Każda wywołanie chmurowego baz danych wektorowych, każda prośba embed() do OpenAI oraz każda operacja upsert() w Pinecone to moment, w którym dane opuszczają twoją sieć.

Wiele rzeczywistych implementacji jest już w pełni odizolowanych od sieci zewnętrznych. W UC San Diego system Onyx obsługuje 37 000 użytkowników bez potrzeby korzystania z Internetu, a Ramp, Thales, L3Harris i Astranis używają podobnych rozwiązań. Hasło reklamowe turbovec – brak usług zarządzanych oraz brak danych opuszczających twoją maszynę lub VPC – doskonale pasuje do tej grupy. Połącz to z lokalnie hostowanym modelem embeddingowym, takim jak BGE-M3 lub BGE-large-en-v1.5, a proces wyszukiwania nie wymaga żadnych połączeń z zewnętrzną siecią.

Brak książki kodów do szkolenia

Ta zaleta ma charakter strukturalny i łatwo ją niedoceniać. Klasyczna kwantyzacja produktów, czyli PQ w IndexPQ i IndexIVFPQ, wymaga książki kodów wytrenowanej na reprezentatywnych danych. Gdy dane ulegają zmianom – na przykład pojawiają się nowe kategorie produktów, nowe języki lub nowe typy dokumentów – książka kodów staje się przestarzała, co negatywnie wpływa na dokładność wyszukiwania.

TurboQuant w ogóle nie posiada książki kodów. Losowa rotacja sprawia, że wzory matematyczne działają niezależnie od tego, jak wyglądają dane wejściowe. W praktyce oznacza to:

  • Wprowadzanie danych w formie strumieniowej odbywa się bez problemów, bez konieczności ponownego trenowania w całości.
  • Zmiana modeli embeddingów, od OpenAI po BGE i Voyage, nie wymusza budowy indeksu od zera.
  • Indeksy wielu użytkowników nie wymagają kalibracji dla każdego z nich osobno.
  • Problem początkowego etapu działania, w którym brakuje wektorów niezbędnych do stworzenia przyzwoitej książki kodów, znika.

Dla systemów, które rozwijają się stopniowo lub obejmują mieszane typy dokumentów, taka prostota stanowi prawdziwą przewagę operacyjną.

Kiedy użyć czegoś innego

Pewne wzory wyszukiwania lepiej sprawdzają się w innych rozwiązaniach, więc najlepiej być wobec tego szczerym.

  • Wyszukiwanie o wysokim wskaźniku odnalezienia. HNSW z wektorami pełnej precyzji pozostaje złotym standardem. turbovec poświęca kilka punktów wskaźnika odnalezienia w zamian za 16-krotną kompresję. Jest to akceptowalne w większości zadań typu RAG, ale problematyczne, gdy brak wyniku ma duże konsekwencje.
  • Filtrowanie metadanych i wyszukiwanie hybrydowe. turbovec to jedynie indeks, bez towarzyszącej mu bazy danych. Zadania takie jak „znajdź wektory bliskie X, ograniczone do dokumentów oznaczonych jako compliance i edytowanych po grudniu 2025 roku” wymagają prawdziwej bazy danych wektorowej, takiej jak Qdrant, Weaviate, Milvus lub pgvector.
  • Embeddingi o niskiej wymiarowości (256 wymiarów lub mniej). Jak sam dokument README przyznaje, turbovec jest o 3 do 6 punktów dokładności mniej skuteczny niż FAISS w przypadku modelu GloVe przy d=200, ponieważ aproksymacja od Beta do Gaussa jest bardziej swobodna przy małej liczbie wymiarów, co zmniejsza przewagę tej teorii. Jeśli stos używa starszych lub mniej wydajnych modeli embeddingów, FAISS jest bezpieczniejszym wyborem.
  • Skala miliardów wektorów. turbovec przeszukuje każdy skompresowany wektor w sposób wyczerpujący. To wystarcza do około 100 milionów wektorów. Po tym progu konieczne jest użycie metod takich jak IVF lub podział oparty na grafach, których turbovec nie oferuje.
  • Preferencja dla usług hostowanych. Zespół, który chce zarządzaną bazę danych wektorowych z kluczem API, uzna turbovec za niewłaściwy narzędzie, bez względu na jakość jego implementacji.

Pierwsze kroki

Dla wyszukiwania w pamięci operacyjnej w zakresie od 100 tysięcy do 100 milionów wektorów o wymiarach 384 lub większych, przy zespole gotowym do zarządzania własną infrastrukturą, oto praktyczne rozwiązanie. Zainstaluj z PyPI:

pip install turbovec

Projekty w Rust dodają zamiast tego crate:

cargo add turbovec

Podstawowe użycie wymaga kilku linijek kodu do utworzenia i zapytania indeksu:

from turbovec import TurboQuantIndex

# Build the index
index = TurboQuantIndex(dim=1536, bit_width=4)
index.add(document_embeddings)
# Search
scores, indices = index.search(query_embedding, k=10)
# Persist
index.write("kb.tq")
loaded = TurboQuantIndex.load("kb.tq")

To jest cała powierzchnia dla prostego przypadku.

Wybór szerokości bitu

To najważniejsza ustawienie, a kompromis jest prosty.

  • 2-bit: 16-krotna kompresja w porównaniu z float32, większa luka w dokładności odzyskiwania danych oraz większa wrażliwość na wymiary.
  • 4-bit: 8-krotna kompresja, przy dokładności odzyskiwania danych zasadniczo porównywalnej z FAISS w przypadku wektorów o 1536 i 3072 wymiarach dostępnych w OpenAI. Obie metody osiągają wartość 1,0 przy k od 4 do 8.

Rozsądna domyślna wartość to 4-bit. Przejdź na 2-bit tylko po zmierzeniu rzeczywistego obciążenia pamięci oraz wpływu na dokładność odzyskiwania danych dla własnych zapytań.

Wybór typu indeksu

Istnieją dwa rodzaje. TurboQuantIndex adresuje wektory według ich pozycji, co sprawia, że rozwiązanie jest proste i nieco szybsze, gdy ID odpowiadają po prostu kolejności wprowadzania. IdMapIndex umożliwia używanie własnych ID typu uint64 oraz usuwanie wpisów w czasie stałym, więc jest lepszym wyborem, gdy klucze pochodzą z bazy danych lub dokumenty są usuwane.

Dla większości systemów RAG IdMapIndex jest lepszym standardowym wyborem, ponieważ ID z bazy danych aplikacji przetrwają usuwanie i ponowną konstrukcję bez uszkodzenia zewnętrznych odniesień.

from turbovec import IdMapIndex
import numpy as np

index = IdMapIndex(dim=1536, bit_width=4)
index.add_with_ids(vectors, np.array([1001, 1002, 1003], dtype=np.uint64))
scores, ids = index.search(query, k=10)  # returns your IDs
index.remove(1002)  # O(1) by ID

Modele embeddingowe

Dla wyszukiwania w środowisku izolowanym model embeddingowy musi działać lokalnie, ponieważ korzystanie z API OpenAI unieważnia korzyści związane z ochroną prywatności. Dwie kombinacje zostały dobrze przetestowane:

  • BGE-M3 z turbovec. Silny model wielojęzyczny, który działa lokalnie i stanowi dobry standard dla międzynarodowych baz wiedzy.
  • BGE-large-en-v1.5 z turbovec. Dedykowany wyłącznie językowi angielskiemu, mniejszy i szybszy, oraz dobry standard dla dokumentacji w języku angielskim.

Gdy ochrona prywatności nie jest surowym wymogiem, modele text-embedding-3-small (1536 wymiarów) lub text-embedding-3-large (3072) od OpenAI dobrze funkcjonują z turbovec. Pamiętaj jednak, że to wywołanie modelu w chmurze, a nie sam indeks, powoduje wyciek danych.

Integracje z frameworkami

turbovec oferuje doskonałe integracje z LangChain, LlamaIndex i Haystack:

pip install turbovec[langchain]
pip install turbovec[llama-index]
pip install turbovec[haystack]

Stos już utworzony na jednym z tych systemów powinien wybrać tę drogę, ponieważ wiąże się z najmniejszym oporem.

Ograniczenia, które należy mieć na uwadze

  • Jedna maszyna, w pamięci. Nie ma trybu rozproszonego, więc skalowanie poziome oznacza dzielenie na fragmenty na warstwie aplikacji.
  • Skanowanie w pełni. Każdy skompresowany wektor jest skanowany przy każdej zapytaniu. SIMD utrzymuje taką szybkość do około 100 milionów wektorów, a po tym wymagana jest metoda IVF lub warstwa grafowa.
  • Zależność od sprzętu. 12 do 20 procent wzrostu wydajności u ARM zostało zmierzone na chipach serii Apple M. Starsze procesory ARM lub x86 bez AVX-512 dają mniejsze korzyści, choć nadal przewyższają FAISS w większości konfiguracji.
  • Pamięć przy niskiej liczbie wymiarów. Poniżej około 256 wymiarów FAISS wygrywa z wyraźną przewagą. Metoda ta działa najlepiej przy 768 lub więcej wymiarach, które generują obecne modele embeddingów.

Wszystko w większym kontekście

turbovec zajmuje określoną niszę: wyszukiwanie wektorowe w pamięci, korpusy średniej wielkości, infrastruktura własna oraz wymiary generowane przez nowoczesne modele embeddingów. Nie próbuje zastąpić Qdrant ani Pinecone. Jest to element budulcowy niższego poziomu, który mógłby zastąpić FAISS, oferujący lepszą kompresję i brak konieczności szkolenia.

Historia powstania tego rozwiązania jest zapewne najciekawszą częścią. Artykuł napisany przez czterech autorów z Google Research został przyjęty na konferencję ICLR 2026; autorzy nie udostępnili żadnego kodu, a dwóch deweloperów z społeczności samodzielnie stworzyło implementacje – jedną do kompresji KV-cache, a drugą do wyszukiwania wektorowego. Ta druga implementacja przewyższa obecne rozwiązania w testach przeprowadzonych na ich własnych bazach danych.

Ścieżka od algorytmu akademickiego, przez jego wdrożenie w społeczności, aż po bibliotekę klasy produkcyjnej przewyższającą standardowe narzędzia będzie się powtarzać, ponieważ wyniki badań rozwijają się szybciej, niż dostawcy są w stanie je przekuć w produkty. turbovec to jeden z przykładów takiego rozwiązania. Zrozumienie jego działania oraz miejsca, które zajmuje w obecnym kontekście, jest przydatne dla każdego, kto projektuje systemy wyszukiwania.