123個Star,4次Fork,這個數字在GitHub上不算顯眼。但點進Live Demo的人會發現,一個1024維的向量搜索任務,在瀏覽器里跑出了接近原生的速度。
這是TurboQuant-WASM——Google Research一篇ICLR 2026論文的瀏覽器移植版。開發者teamchong用Zig重寫,再編譯成WASM,最后塞進npm包。整個鏈條的終點,是你在Chrome里跑向量量化,壓縮率約6倍,批量點積查詢比單條循環快83倍。
從論文到瀏覽器,中間隔著多少坑
向量量化(Vector Quantization,VQ)不是新東西。把高維浮點數壓縮成低維表示,省空間、加速檢索,這是推薦系統和RAG(檢索增強生成)的基建。但學術界的東西進瀏覽器,通常要脫層皮。
原論文TurboQuant的核心賣點是"在線量化"——流式數據進來,邊學邊壓,不需要預訓練碼本。這對邊緣場景很友好,但論文里的實現是Zig原生代碼,依賴SIMD指令集。瀏覽器沒有AVX-512,甚至連穩定的SIMD支持都是近年才補齊。
teamchong的解法分三層:先用Zig的relaxed SIMD做數學運算,@mulAdd直接映射到f32x4.relaxed_madd;再把QJL(一種隨機投影簽名算法)的打包解包邏輯向量化;最后用TypeScript包一層皮,暴露init/encode/decode/dot四個方法。
relaxed SIMD是關鍵妥協。標準WASM SIMD要求嚴格的IEEE 754精度,relaxed SIMD允許硬件用更快的指令,比如把乘加融合(FMA)做成單條指令。代價是結果可能因CPU而異,但向量量化本身對微小誤差有容忍度——論文里的distortion bound保證了這點。
6倍壓縮是怎么算的
看代碼里的參數:dim=1024,輸出compressed是Uint8Array。約4.5 bits/dim的壓縮率,算下來每個原始float32(32比特)被壓到4.5比特,壓縮比7.1倍。但官方README寫的是"~6x compression",取的是保守估計,留足安全邊際。
實際調用鏈很干凈:TurboQuant.init()做一次性初始化,seed固定隨機投影矩陣;encode把Float32Array轉成壓縮字節流;decode還原;dot和dotBatch做相似度計算,后者把一批壓縮向量concatenate后一次性送進WASM,避免JS-WASM邊界往返。
83倍加速來自批量接口的設計。單條dot()每次都要跨邊界調用WASM,dotBatch()把N個向量拼成一塊內存,一次調用返回全部得分。這是邊緣計算的經典trade-off:省帶寬(壓縮)換延遲,再用批處理攤平調用開銷。
瀏覽器兼容性寫在明處:需要支持relaxed SIMD的WASM引擎。Chrome 119+、Firefox 120+、Safari 17+都達標,但舊版瀏覽器會直接拋異常。這是技術選型時的清醒切割——不追求全覆蓋,先拿下能跑的場景。
誰需要瀏覽器里的向量量化
Demo里放了三個場景:向量搜索、圖像相似度、3D高斯潑濺(Gaussian Splatting)壓縮。前兩個是RAG和視覺搜索的標準用例,第三個更微妙——3DGS的顯存占用是落地瓶頸,瀏覽器端壓縮能緩解WebGL紋理壓力。
一個具體的想象:你在做一個攝影社區,用戶上傳照片后自動找相似風格。傳統做法是把特征向量傳回服務器,現在可以瀏覽器里算完,只傳壓縮后的字節。6倍壓縮意味著帶寬成本打六折,或者同樣帶寬下多傳6倍數據。
但限制也很硬。TurboQuant是在線算法,適合流式場景,不適合已經固化的海量索引。如果你的向量庫是靜態的、預先算好的,用傳統PQ(Product Quantization)或HNSW索引會更省。換句話說,這是為"邊來邊壓"設計的工具,不是萬能藥。
build.zig.zon文件暴露了依賴:基于botirk38/turboquant的Zig實現,用golden-value tests保證字節級一致。測試命令是zig test -target aarch64-macos,跨平臺編譯的野心寫在配置里。
Zig+WASM的組合為什么值得看
選Zig而不是Rust或C++,是個值得品味的決定。Zig的編譯時計算和顯式內存控制,對WASM這種資源受限目標很友好。build腳本里bun run build:zig直接調Zig編譯器,再用wasm-opt做二進制優化,最后用bun+TypeScript打包——整個工具鏈沒有Webpack或Rollup的臃腫。
relaxed SIMD的啟用需要顯式配置,Zig的@mulAdd內置函數正好映射到這條指令。對比Rust的std::simd,Zig的底層控制更直接,代價是安全邊界更薄。teamchong用golden-value tests兜底:同一組輸入,Zig原生輸出和WASM輸出逐字節比對。
npm包的體積沒寫在README里,但嵌入base64編碼的WASM是常規操作。預估在100KB-300KB區間,對現代Web應用可接受,但移動端仍需斟酌。
API設計顯露出產品經理思維:四個方法覆蓋90%場景,destroy()顯式釋放內存,避免WASM堆的泄漏焦慮。沒有暴露底層的投影矩陣,seed參數固定隨機性,降低誤用風險。
GitHub頁面的4個Fork里,有一個是fork到本地后改target為x86_64的嘗試——社區已經開始魔改。但relaxed SIMD的指令集差異意味著,aarch64和x86_64的WASM二進制不能混用,這是移植時必須吞下的苦果。
論文的distortion bound保證了量化誤差可控,但瀏覽器里的浮點行為本身就有平臺差異。teamchong的測試矩陣覆蓋了多少組合,README沒提。這是開源項目的常見誠實:核心功能verified,邊緣情況留待社區踩坑。
如果向量搜索的延遲能從百毫秒壓到十毫秒,RAG應用的用戶體驗會跨過一道門檻。TurboQuant-WASM沒承諾這個,但它把Google Research的算法變成了npm install就能試的東西——中間隔著Zig編譯器、WASM SIMD規范和83倍加速的批量接口,這些細節堆起來,就是學術到工程的完整距離。
下一個問題是:當你的用戶上傳第100萬張圖片時,瀏覽器里的在線量化,和服務器端的預建索引,哪個會先摸到天花板?
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.