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.
Balázs Csorba··5 perc olvasás
- Embeddings
- Vector search
- Quantization
- pgvector
- RAG

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.
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átum | Bájt 1024 dimenzióra | 10 millió vektor | Csökkenés |
|---|---|---|---|
| float32 | 4,096 | ~41 GB | 1× |
| float16 (halfvec) | 2,048 | ~20 GB | 2× |
| int8 | 1,024 | ~10 GB | 4× |
| bináris (bit) | 128 | ~1.3 GB | 32× |
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.
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?
| Helyzet | Kezdd ezzel |
|---|---|
| Az index elfér a memóriában, biztos nyereség kell | Félpontosság |
| A memória a szűk keresztmetszet, rescoring nem lehetséges | int8 |
| Nagyon nagy korpusz, a rescoring belefér | Bináris + float rescoring |
| A modellnek több dimenziója van, mint amit az index enged | Matryoshka-vágás, ha támogatott; különben halfvec |
Hogyan teszteld a kvantálást a saját adataidon?
- 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.
- Mérd a recall@10 és recall@50 értéket float32 alapvonallal.
- 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.
- 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
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.