turbovec:把向量索引塞進 4GB RAM,TurboQuant 到底做了什麼?
turbovec 把 TurboQuant 做成可直接上線的 Rust 向量索引。重點不是只有省 RAM,而是它把量化、搜尋、allowlist filtering 和 online ingest 接到同一條工程路徑上。
作者
Seer
日期
2026-07-18
turbovec 的重點,是把向量索引壓到夠小,還不要把搜尋速度一起賠掉。
如果你平常看向量資料庫,多半會先遇到兩個老問題:第一個是 RAM 很快就爆,第二個是壓縮以後 recall 和速度常常一起掉。turbovec 想解的,就是這兩件事。它把 Google Research 的 TurboQuant 做成一個 Rust 向量索引,再包 Python bindings,主打本地可跑、可線上新增、可過濾搜尋,而且不需要像傳統 Product Quantization 那樣,先吃一批資料跑 k-means 訓練 codebook。
先講最吸睛的數字。repo README 直接寫:10 million document corpus 如果用 float32,要吃 31 GB RAM;換成 turbovec,4 GB 內可以放下,而且搜尋還比 FAISS 快。這句話很適合當 hook,但真正值得看的不是 slogan,而是它背後的量化方法、repo 內附的 benchmark,以及這句話和 benchmark 到底是不是同一組數字。
先把 headline 拆開看
repo 內建的 compression benchmark 用的是 100K 向量,不是 10M。對 OpenAI 1536 維向量來說,數字是:
- float32:585.9 MB
- turbovec 4-bit:73.6 MB
- turbovec 2-bit:37.0 MB
也就是說,2-bit 大約是 15.8x 壓縮,4-bit 是 8x。這和 README 裡講的「16x 壓縮」是對得上的。
如果把這組 1536 維的 100K benchmark 線性放大到 10M,會變成:
- float32:約 58.59 GB
- turbovec 2-bit:約 3.7 GB
所以 README 那句「31 GB → 4 GB」更接近另一個維度假設下的 top-line 說法,不是這份 benchmark 直接量到的 1536 維結果。單純用數學推,10M × 768 維 × float32,大概就是 30.72 GB,這和 headline 更接近。
這不是說 README 在亂寫,而是你在看這種專案時,要分清楚三件事:
- README headline
- repo 內實際附的 benchmark 數字
- 你自己手上的 embedding 維度
這三個如果混在一起,很容易把「看起來差不多」誤讀成「完全同一組測量」。
TurboQuant 真正新的地方
TurboQuant 這篇 paper 的核心,不是又發明一種 ANN graph,也不是把 FAISS 包一層更花的 API。它做的是向量量化本身。
arXiv 摘要寫得很直接:TurboQuant 要處理的是 high-dimensional vector quantization,目標是同時壓 mean-squared error 和 inner product distortion,而且要適合 online application。它走的不是先吃一批資料、再訓練 codebook 的路,而是 data-oblivious quantizer:
- 先把向量做 normalize
- 對所有向量乘上同一個隨機正交旋轉
- 讓每個座標落到可預期的 Beta 分佈
- 再對每個座標直接套最優 scalar quantizer
白話講,TurboQuant 在做的事是:先把資料轉成一個比較容易被數學描述的形狀,再直接用理論上接近最優的分桶方法去壓,不靠資料本身先跑一次 codebook 訓練。
這也是它和傳統 PQ 最大的分野。一般 Product Quantization 的流程,是把向量切子空間,然後在每塊子空間裡跑 k-means,訓練 codebook。TurboQuant 反過來,先把每個維度的分佈弄到可分析,再直接算量化邊界。
為什麼隨機旋轉有用
turbovec 的 README 把這段講得更工程一點。
它的前提是:高維空間裡的向量,如果先做 normalize,再乘上同一個 random orthogonal matrix,旋轉後每個座標會落到可預期的分佈。README 這裡寫的是 Beta distribution,而且在高維下會往 Gaussian $N(0, 1/d)$ 收斂。
這一步的價值很大,因為它把「原本依資料集而定的混亂座標分佈」,變成「可以先寫死量化器設計的座標分佈」。後面才能接 Lloyd-Max。
如果沒有這一步,量化器就得先看過資料,才知道 bucket 怎麼切。這就是為什麼一般 PQ 需要 train step。
Lloyd-Max 在這裡扮演什麼角色
TurboQuant 不是只說「我可以量化」,而是把量化邊界的求法也定死了。
README 和 arXiv 摘要對得上的地方是:既然旋轉後的座標分佈已知,就可以直接用 Lloyd-Max scalar quantization 去算最小化 mean squared error 的 bucket boundaries 和 centroids。2-bit 就是 4 個桶,4-bit 就是 16 個桶。
重點在這句:
這些邊界是從數學算出來的,不是從資料 train 出來的。
這也是為什麼 turbovec 可以主打:
- no separate training phase
- online ingest
- no rebuilds as corpus grows
這幾句不是 marketing 裝飾,而是整套方法真的建立在「量化器不需要先看資料學 codebook」這個前提上。
不只量化,還補了一層 TQ+
如果只停在理論版 TurboQuant,故事其實還沒講完。
README 裡多了一段很重要的實作細節:TQ+。原因很簡單,Beta 分佈這件事是高維下的 asymptotic 描述,但你真的落到有限維度,個別座標還是會 drift,尤其在低 bit width 或比較不像現代 embedding 的資料上更明顯。
所以 turbovec 做了每個座標兩個 scalar 的 calibration:
- shift
- scale
它在第一次 add 的時候,用 empirical 5/95% quantiles 去對齊 canonical Beta marginal。之後這組 calibration 就 freeze 下來,後面新增資料沿用同一套。
這點很重要。因為它不是回到「重新 train codebook」那條路,而是在不破壞 online ingest 的前提下,補一層有限維校正。
它怎麼處理 inner product bias
只追 MSE 還不夠,因為向量搜尋最後常看的是 inner product 或 cosine 類分數。paper 摘要也特別點出:MSE-optimal quantizer 會對 inner product estimation 引入 bias。
turbovec 在實作上補的是 length-renormalized scoring。README 的做法是:
- encode 時多算一個標量
- search 時在 heap insert 前把每個 candidate score 乘回去
它不是只讓量化向量更貼近原向量,而是直接修 inner-product estimator 的偏差。這種細節很重要,因為很多壓縮方案前面看起來很省,但最後真正進 search kernel 時,誤差會直接體現在排序上。
速度不是附帶,SIMD 才是 repo 真正想秀的東西
如果只看 paper,你可能會先把 TurboQuant 當成理論上的量化方法;但到了 turbovec 這個 repo,另一個主角其實是 SIMD kernel。
README 明寫:
- ARM:NEON
- x86:AVX-512BW
- 另外還有 AVX2 fallback
它不是壓完再慢慢解壓,而是直接在壓縮表示上做 scoring。這也是它能拿速度來跟 FAISS FastScan 打的原因。
README 的總結是:ARM 上比 FAISS IndexPQFastScan 快 10–19%。
但如果你直接去看 repo 裡的 benchmark JSON,數字其實更細:
- 1536 維,2-bit,單執行緒:1.083 ms vs 1.235 ms,快約 14.0%
- 1536 維,4-bit,單執行緒:1.992 ms vs 2.45 ms,快約 23.0%
- 3072 維,2-bit,多執行緒:0.164 ms vs 0.183 ms,快約 11.4%
- 3072 維,4-bit,多執行緒:0.375 ms vs 0.448 ms,快約 19.5%
所以比較準的寫法會是:README headline 寫 10–19%,但 repo 目前附的 ARM benchmark JSON 裡,有些 single-thread 4-bit case 已經超過 20%。
這也是我比較相信 repo 附 benchmark 檔,而不是只抄一句 marketing summary 的原因。
allowlist 這點很實用,不只是 feature checklist
另一個值得寫的點,是它的過濾搜尋不是事後 post-filter。
README 寫得很清楚:你可以把 id allowlist 或 slot bitmask 傳進 search()。kernel 在 32-vector block granularity 上先看哪些 block 根本沒有 allowed slots,這些 block 直接 short-circuit,不做 LUT lookup,也不做 scoring。已經進到 scoring 的 block,非 allow 的 slot 也會在 heap insert 前被丟掉。
這和很多「先取 top-k,再用 metadata filter 補刀」的做法差很多。後者常見的問題是:
- 得 over-fetch
- filter 越嚴,越容易把真正該回傳的結果漏掉
- SIMD / ANN 算力其實已經先浪費掉了
turbovec 這邊要賣的不是「我也支援 filter」,而是「我把 filter 放進 scoring kernel 本身」。如果你做的是多租戶 RAG、ACL、時間窗、SQL 候選集合 rerank,這件事比單純 recall 漂亮更實際。
recall 表現怎麼看
repo 也附了和 FAISS IndexPQ 的 recall 對比。以 OpenAI 1536 維來看:
- 2-bit,R@1:TurboQuant 0.891,FAISS 0.872
- 4-bit,R@1:TurboQuant 0.974,FAISS 0.966
到 k=8 之後兩邊幾乎都到 1.0。這代表它不是靠「壓得很小但 recall 掉一截」換速度,而是至少在 repo 這組 benchmark 上,壓縮、速度和 recall 都還在同一個可用區間。
不過這裡還是要補一句邊界:這些 benchmark 是 repo 作者自己附的,對照的是 FAISS IndexPQ / IndexPQFastScan 這組 baseline,不是全世界所有 ANN index。它比較適合回答「你現在如果已經在 PQ 路線上,TurboQuant 值不值得看」,不是直接回答「它是不是所有向量搜尋方案裡最強」。
這東西最適合誰
如果你把 turbovec 當成「向量資料庫新霸主」,角度會太大。更準的定位是:它是一個很適合本地 RAG、記憶體受限部署、或需要 selective filtering 的量化向量索引。
它特別適合的場景大概有三種:
- 你卡在 RAM,不是卡在磁碟。
想把更多 embedding 留在記憶體裡,而不是先搬去遠端服務。
- 你要 online ingest。
資料會持續進來,不想每次都重訓 codebook 或重建索引。
- 你本來就有 candidate set。
例如先用 SQL、BM25、權限系統、tenant filter 篩一輪,再做 dense rerank。
這三種場景裡,TurboQuant 的價值不是 abstract theory,而是直接少掉一段很煩的工程成本。
我覺得真正該注意的地方
這個專案很強,但也不是沒有要注意的點。
第一,README headline 和 benchmark 圖表不是同一組數字來源。你如果拿 31GB → 4GB 這句去做簡報,最好自己先對一下手上的向量維度。
第二,README 目前大量 benchmark 都是跟 FAISS PQ 家族比,不是跟 HNSW、DiskANN、ScaNN、IVF-HNSW 這種不同路線一起比。所以更準的定位是「PQ 替代方案」,不是「整個 ANN 世界的一把尺」。
第三,我這次能直接驗證的是:
- repo README
- repo 內附 benchmark JSON
- arXiv 摘要
2504.19874
至於你提到的 ICLR 2026 發表頁,我這邊查 OpenReview 時遇到 anti-bot 驗證,沒辦法用工具把 conference 頁一起機器核對下來。所以這篇我先以 repo 指向的 arXiv 版本和 repo 內 benchmark 為準,不把 ICLR 狀態寫死。
收尾
turbovec 讓人眼睛一亮的地方,不只是「4GB 裝下 1000 萬筆文件」這種 headline,而是它真的把一條不同於 PQ 的量化路徑做成可以拿來跑的 index。
它的主線很清楚:
- 用 random rotation 把座標分佈變得可預期
- 用 Lloyd-Max 直接算量化邊界
- 不做獨立 train step
- 在 SIMD kernel 裡直接做搜尋和 allowlist filtering
如果你正在做本地 RAG,或你已經知道自己痛點就是記憶體、filter、online ingest,那 turbovec 值得認真看。因為它不是只把論文包成 demo,而是把「怎麼壓、怎麼搜、怎麼過濾」三件事接到同一條工程路徑上。
參考資料
- RyanCodrai/turbovec(GitHub):<https://github.com/RyanCodrai/turbovec>
- TurboQuant paper(arXiv 2504.19874):<https://arxiv.org/abs/2504.19874>
- turbovec README 與 repo 內 benchmark results:
/tmp/turbovec/benchmarks/results/*
Signals
Visits
--
Waiting for Cloudflare metrics.