Blog/Retrieval és keresés

Embedding-kvantálás: bináris, int8 és Matryoshka vektorok a visszakeresés minőségének elvesztése nélkül

Hogyan zsugorítja 4–32-szeresére a vektorindexet a bináris és int8 kvantálás és a Matryoshka-vágás, mennyibe kerül ez, és hogyan hozza vissza a rescoring.

··5 perc olvasás

  • Embeddings
  • Vector search
  • Quantization
  • pgvector
  • RAG
Egy float32 embedding félpontosságúvá, int8-cá és bináris bitekké zsugorodik, egy rescoring lépés pedig visszaállítja a rangsorolás minőségét.

A lényeg röviden

  • A bináris kvantálás dimenziónként egy bitet tárol, 32-szer kevesebbet, mint a float32; az int8 egy bájtot, 4-szer kevesebbet.
  • A Hugging Face tesztjeiben a bináris embeddingek a visszakeresési teljesítmény nagyjából 92,5%-át tartották meg, a float lekérdezéssel végzett rescoring ezt kb. 96%-ra emelte.
  • A Matryoshka-modelleknél elég az első dimenziókat megtartani; az OpenAI text-embedding-3-large 12-szeres tömörítésnél 93,1%-ot tartott meg.
  • A pgvector támogatja a halfvec típust 4000, a bit típust 64 000 dimenzióig, a bináris kvantálást pedig kifejezésindexszel és újrarangsorolással.
  • Az indexet kvantáld, a teljes vektorokat tartsd meg a lemezen, és a saját lekérdezéseiden mérd a felidézést előtte és utána.

Cikk meghallgatása

0:000:00

A vektorindexek gyorsabban drágulnak, mint gondolnánk. Tízmillió chunk 1024 dimenziós float32 embeddingekkel nagyjából 41 GB nyers vektor, még bármilyen indexterhelés előtt, a HNSW-indexek pedig a memóriában szeretnek lenni. Jóval azelőtt, hogy az embedding-modell vagy az adatbázis gondot okozna, a RAM lesz a szűk keresztmetszet. A kvantálás 2–32-szeresére zsugorítja ezeket a vektorokat, és egy plusz lépéssel meglepően kevés visszakeresési minőségbe kerül.

A cikk összeveti a félpontosságot, az int8-at, a bináris kvantálást és a Matryoshka-vágást a mért megtartási számokkal, bemutatja a megvalósítást pgvectorban, és egy saját korpuszra szabott teszttervvel zárul. Magát a tárolóválasztást a pgvector vagy vektoradatbázis cikk tárgyalja.

Mit csinál valójában az embedding-kvantálás?

Ez a vektorokon végzett utófeldolgozás, nem a modellen. Ahogy a Hugging Face írása fogalmaz, a bináris kvantálás minden float32 értéket nullánál húzott küszöbbel egy bitté alakít, ami 32-szeres memória- és tárhelycsökkenést jelent; a skaláris int8 kvantálás minden értéket 256 tartomány egyikére képez le, ez 4-szeres csökkenés. A bináris vektorokat Hamming-távolsággal hasonlítjuk össze, amely nagyon olcsón számolható.

FormátumBájt 1024 dimenzióra10 millió vektorCsökkenés
float324,096~41 GB1×
float16 (halfvec)2,048~20 GB2×
int81,024~10 GB4×
bináris (bit)128~1.3 GB32×

A számok nyers vektorméretek; az indexek ezen felül nagyjából arányos többletet adnak. A lényeg a nagyságrend: a bináris egy külön szervert igénylő problémát olyanná tesz, ami elfér az alkalmazás mellett.

Mennyi visszakeresési minőséget veszítesz?

A Hugging Face ezt az mxbai-embed-large-v1 modellel mérte MTEB visszakeresésen. A bináris embeddingek önmagukban a float32 teljesítmény nagyjából 92,5%-át tartották meg. Egy rescoring lépés – a jelöltek bináris lekérdezéssel való lekérése, majd float32 lekérdezés-embeddinggel való pontozása – ezt kb. 96%-ra emelte, miközben az index 32-szeres memóriamegtakarítása megmaradt. Az int8 a kettő között van, és biztonságosabb választás, ha nem fér bele egy rescoring kör.

Bináris visszakeresés rescoringgalA lekérdezést egyszer float32-ben embeddeljük. Egy bináris másolat a szükségesnél többszörös számú jelöltet keres a bináris indexben. A jelölteket a float32 lekérdezéssel a tárolt teljes vektoraik alapján újrapontozzuk, a legjobb találatok pedig a rerankerhez vagy a modellhez kerülnek.Lekérdezésfloat32Bináris keresésHamming, k×4Újrapontozásteljes vektorokRerankopcionálisTop ka modellnek
Csak a bináris indexnek kell a memóriában lennie; a teljes vektorokat lekérdezésenként néhány száz jelöltre olvassuk be.

Mit adnak hozzá a Matryoshka-embeddingek?

A kvantálás a dimenziónkénti bitek számát csökkenti. A Matryoshka Representation Learning a dimenziók számát: a modelleket úgy tanítják, hogy az első dimenziók hordozzák a legtöbb információt, és a vektor egy előtagja önmagában is használható embedding. Az eredeti tanulmány ImageNet-osztályozáson azonos pontosság mellett akár 14-szer kisebb embeddingekről számol be. Szövegre a Hugging Face írása szerint az OpenAI text-embedding-3-large 12-szeres tömörítésnél a teljesítmény 93,1%-át, a nomic-embed-text-v1.5 3-szorosnál 95,8%-ot, 6-szorosnál 90%-ot tart meg.

A vágás csak az így tanított modelleknél működik. Egy közönséges modell dimenzióinak levágása jelentősen rontja a minőséget, a klasszikus dimenziócsökkentés, például a PCA pedig embeddingeken általában gyengén teljesít, ahogy ugyanez az írás megjegyzi. Vágás előtt nézd meg a modellkártyát.

Hogyan csináld ezt pgvectorban?

A pgvector README felsorolja a HNSW-indexek korlátait: vector 2000, halfvec 4000, bit 64 000 dimenzióig. A bináris kvantálás a binary_quantize(embedding) kifejezésre épített indexszel és Hamming-távolsággal működik, ugyanaz a lekérdezés pedig az eredeti vektorokkal újrarangsorolhatja a jelölteket. A subvektor-kifejezésindexek második oszlop nélkül adják a Matryoshka-vágást.

-- Binary index for candidate search, full vectors for rescoring
CREATE INDEX chunks_bq ON chunks
  USING hnsw ((binary_quantize(embedding)::bit(1024)) bit_hamming_ops);

SELECT id, text FROM (
  SELECT id, text, embedding FROM chunks
  ORDER BY binary_quantize(embedding)::bit(1024) <~> binary_quantize($1::vector)
  LIMIT 200                                   -- 4–10x the final k
) candidates
ORDER BY embedding <=> $1::vector             -- rescore with the float query
LIMIT 20;

-- Matryoshka: index only the first 512 dimensions of a model trained for it
CREATE INDEX chunks_mrl ON chunks
  USING hnsw ((subvector(embedding, 1, 512)::vector(512)) vector_cosine_ops);

-- Half precision: half the memory, nearly no loss
CREATE INDEX chunks_half ON chunks
  USING hnsw ((embedding::halfvec(1024)) halfvec_cosine_ops);

A lekérdezésnek ugyanazt a kifejezést kell használnia, mint az indexnek, különben a Postgres szekvenciális olvasásra vált. Lekérdezésformánként egyszer ellenőrizd EXPLAIN-nel. A dedikált vektoradatbázisok, például a Qdrant, a skaláris és bináris kvantálást gyűjteménybeállításként, beépített rescoringgal kínálják; a kompromisszumok ugyanazok.

Melyik technikát válaszd?

HelyzetKezdd ezzel
Az index elfér a memóriában, biztos nyereség kellFélpontosság
A memória a szűk keresztmetszet, rescoring nem lehetségesint8
Nagyon nagy korpusz, a rescoring beleférBináris + float rescoring
A modellnek több dimenziója van, mint amit az index engedMatryoshka-vágás, ha támogatott; különben halfvec

Hogyan teszteld a kvantálást a saját adataidon?

  1. Vedd a visszakeresési értékelőkészletedet, ismert releváns chunkokkal rendelkező kérdéseket, ahogy a RAG értékelése cikkben leírtam.
  2. Mérd a recall@10 és recall@50 értéket float32 alapvonallal.
  3. Ismételd meg halfvec, int8, rescoring nélküli bináris és a végső k 4- és 10-szeresével végzett rescoringos bináris változatra.
  4. Egy táblázatba írd fel az indexméretet, a p95 lekérdezési késleltetést és a felidézést, és válaszd a felidézési kereteden belüli legolcsóbb lehetőséget.

Utána futtasd le a teljes pipeline-t, a hibrid kereséssel és a rerankerrel együtt az Éles RAG-pipeline cikkből. A reranker gyakran elfedi az első lépcső kis felidézési veszteségeit, ez is oka annak, hogy a kvantált első lépcsős visszakeresés a gyakorlatban jól működik.

Források

  1. Hugging Face: Binary and Scalar Embedding Quantization for Significantly Faster and Cheaper Retrieval (Mar 2024)
  2. Kusupati et al.: Matryoshka Representation Learning (2022)
  3. pgvector README: halfvec, bit, binary quantization and subvector indexing

Gyakori kérdések

Mi az embedding-kvantálás?

Az, hogy az embedding minden értékét kevesebb biten tároljuk, miután a modell előállította: 16 bites lebegőpontos számként, 8 bites egészként vagy dimenziónként egyetlen bitként. A modell nem változik; csak a tárolt vektorok és az index lesz kisebb és gyorsabban összehasonlítható.

Mennyi minőséget veszít a bináris kvantálás?

A Hugging Face mxbai-embed-large-v1 modellel végzett kísérleteiben a bináris embeddingek az MTEB visszakeresési teljesítményének nagyjából 92,5%-át tartották meg. A legjobb jelöltek float32 lekérdezés-embeddinggel végzett újrapontozása ezt kb. 96%-ra emelte. Más modelleken és területeken ez eltérhet, ezért a saját adataidon teszteld.

Mik a Matryoshka-embeddingek?

Olyan embeddingek, amelyeket úgy tanítottak, hogy az első dimenziók hordozzák a legtöbb információt, így rövidebbre vághatók, és a minőség nagy része megmarad. Az OpenAI text-embedding-3 családja és a nomic-embed-text-v1.5 is támogatja ezt.

Használhatok bináris kvantálást PostgreSQL-ben?

Igen. A pgvectorban van binary_quantize függvény, bit típus és Hamming-távolság operátorok, így HNSW kifejezésindexet építhetsz a bináris változatra, és ugyanabban a lekérdezésben újrarangsorolhatod a jelölteket az eredeti vektorokkal.

Előbb kvantáljak vagy vágjak?

Kezdd a félpontossággal, amely szinte ingyenes, majd próbáld az int8-at vagy a binárisat rescoringgal, ha a memória még mindig szűk keresztmetszet. A Matryoshka-vágást akkor használd, ha a modell támogatja, és nem a pontosság, hanem a dimenziószám a korlát, például a pgvector vector típusának 2000 dimenziós indexkorlátja.

Pont erre van szükséged?

Írj a projektedről vagy a pozícióról – szívesen hallok felőled.