ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

RaBitQ 量化深度解析:VexDB-Lite 如何用码字遍历图索引实现极限内存压缩

RaBitQ 量化深度解析:VexDB-Lite 如何用码字遍历图索引实现极限内存压缩 RaBitQ 量化深度解析VexDB-Lite 如何用码字遍历图索引实现极限内存压缩【免费下载链接】VexDB-LiteA cross-platform vector database, which can be integrated into existing databases as a plugin.项目地址: https://gitcode.com/gh_mirrors/ve/VexDB-LiteVexDB-Lite 是一款跨平台向量数据库可嵌入 PostgreSQL、DuckDB、SQLite 作为插件。它的 RaBitQ 量化器能把每条向量压缩成不到 1KB 的「码字」让 HNSW 图索引在百万级向量下依然驻留内存配合memory_modecompact实现极限内存压缩同时保留 L2、cosine、内积三种距离度量。1. 为什么图索引需要「极限内存压缩」以图像检索为例用户丢进来一艘海面上的红船作为查询条件——数据库需要在候选图库里找出最相似的一张比如这幅田野场景——问题在于HNSW 这类图索引搜索时几乎每次比较都要读一条向量。以 768 维 float32 向量计100 万条就要3GB常驻内存。向量一多图索引就从「内存索引」退化成「磁盘索引」查询延迟陡增。RaBitQ 的思路很直接图里不再存原始向量只存量化码字搜索比较全部基于码字完成。码字足够小整个图就能装进内存。2. RaBitQ 码字长什么样把 3072 字节压成 896 字节码字的内存布局定义在 code_distancer.h 中一条 768 维向量的 RaBitQ 码字由 4 部分组成组成部分大小768 维作用8 字节头cluster id 对齐填充8 B记录所属聚类供查询期取用聚类质心1-bit 二值码 3 个校准系数108 B粗排只记每个维度的符号速度极快8-bit 扩展码 3 个校准系数780 B精排恢复幅值信息精度接近原向量合计896 B相比原始 3072 B压缩约3.4 倍尺寸公式见 utils.hRABITQ_BIN_CODE_SIZE每 64 维压成 1 个 64 位字和RABITQ_EXT_CODE_SIZE每维 8 bit外加 3 个 float 校准系数。2.1 先旋转再量化量化前的第一步是把向量乘上一个随机正交矩阵实现见 rotator.h 的FhtKacRotator。它用 Fast Hadamard Transform快速哈达玛变换 随机符号翻转 Kac walk 近似任意正交旋转复杂度接近 O(d log d) 而非 O(d²)。旋转的目的是打散向量能量的分布让各维度幅度尽量均匀——这样「每维只存 1 bit / 8 bit」的粗粒度量化才不会在个别维度上误差爆炸。2.2 两步编码1-bit 符号 8-bit 幅值编码主流程在 rabitq.cpp 的quantize()中向量旋转后就近分配到 16 个聚类质心之一compute_closest_cluster聚类数见HNSW_RABITQ_NUM_CLUSTERS残差 旋转向量 − 质心。残差每维的正负号就是 1-bit 二值码one_bit_code打包成 64 位字存储残差每维的幅值再做 8-bit 标量量化得到扩展码ex_bits_code负数维的码字取反码把符号位「藏」进码值里。所以整条向量 质心16 选 1共享 二值码方向 扩展码幅值这就是「码字」的全部内容。2.3 三个校准系数让估算距离「无偏」纯 1-bit 量化会系统性地歪曲距离。RaBitQ 的巧妙之处在于编码时为每条码字额外存 3 个 float 系数f_add加项、f_rescale缩放项、f_error误差界见 rabitq.cpp 中quantize_bin_code的末尾。查询时距离不再是「算出来的」而是「套公式估出来的」est_dist f_add g_add f_rescale × (ip k1xsumq) low_dist est_dist − f_error × g_error其中ip是查询二值化码与存储二值码的位积SIMD 加速g_add/g_error是查询到质心的距离。low_dist是理论下界真实距离一定 ≥ low_dist。这个下界正是图搜索里「何时可以剪枝」的数学依据。3. 码字如何驱动图遍历code-aware 搜索这是标题里「码字遍历图索引」的核心。整条链路在 estimator.cpp查询预处理只做一次preprocess旋转查询向量、二值化查询码、预计算查询到 16 个质心的距离表q_to_centroids——之后每次节点比较都省掉这些开销两级比较get_bin_dist只用 1-bit 码一次 64 位 POPCNT 级别的位运算就能估算距离 下界用于图搜索的候选粗排与剪枝get_full_dist加上 8-bit 扩展码的浮点内积得到接近原向量精度的距离用于候选集精排。无需 refineCodeDistancer中need_refine falsecode_distancer.h。普通 PQ 索引搜完还要回表取原始向量重排RaBitQ 的 8-bit 码精度已经足够省掉一次随机读。另一条关键能力是码字重构reconstruct()rabitq.cpp可以从码字反推出「质心 残差」的近似向量用于图维护时的邻居选择因此 compact 模式下原始向量在索引侧完全不需要保留。整个索引侧的持久化由宿主适配例如 PostgreSQL 侧在 vexdb_pg/src/rabitq_distancer.cpp 中训练量化器并把码字块写入索引文件。4. 极限内存压缩怎么落地memory_modecompact在 features.md 的 RaBitQ 一节可以查到用法一行 SQL 开启CREATE INDEX idx_rabitq ON items USING vexdb (vec) WITH (metric cosine, quantizer rabitq, memory_mode compact, m 16, ef_construction 160);compact模式下磁盘布局为量化码字与图结构写入索引kind 5/6不写原始向量镜像kind 4用户数据仍完整保存在%_vectors表中。按 768 维、100 万条向量算笔账方案索引侧单条开销1M 条总量原始 fp32 向量3,072 B≈ 3 GBRaBitQ 码字compact896 B≈ 0.85 GB图节点开销之外仅向量数据就省下约70% 内存向量维度越高、数据量越大收益越夸张。查询、增量插入、重启恢复全部基于码字完成无需回表重排。正确性有回归测试兜底可参考 graph_index_rabitq.yaml它覆盖空索引、memory_modecompact落盘校验rabitq_codes_bytes 0、以及 L2 / cosine / inner product 三种度量下的建索引与查询还验证了quantizerrabitq与pq_m互斥的参数约束。5. 选型速览什么时候该上 RaBitQ场景建议内存紧张、向量 ≥ 百万级、768 维左右的 embedding✅ RaBitQ compact内存收益最大追求极限召回、向量数量较小原生 fp32 图索引quantizernone超高维如 1536、想更激进的压缩可对比quantizerpq按召回/内存权衡需要精确回表重排PQcompact 下按ef_search × 1.25扩展候选再重排RaBitQ 通常无需一句话总结VexDB-Lite 的 RaBitQ 量化 FHT 随机旋转 16 聚类残差 1-bit/8-bit 两级码字 三系数无偏估算配合码字下界剪枝和码字重构让 HNSW 图索引在保留搜索精度的同时把内存占用压到原来的三成左右——这正是「图索引 量化」在内存受限场景下的极限形态。【免费下载链接】VexDB-LiteA cross-platform vector database, which can be integrated into existing databases as a plugin.项目地址: https://gitcode.com/gh_mirrors/ve/VexDB-Lite创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表