乘积量化与 IVF-PQ:压缩域里的近似最近邻

💡 原文中文,约12300字,阅读约需30分钟。
📝

内容提要

本文梳理IVF-PQ向量检索:PQ将向量切分子空间并量化压缩,ADC用查找表估距;IVF先粗聚类缩小候选,再对残差编码。实验表明码长增加可降低MSE,但召回受量化误差限制,nprobe增大后召回进入平台。工程上需按内存、召回与候选数调参,并配合OPQ、重排等优化。

🔎

延伸解读

内存账本:别只算PQ码

文章以十亿128维向量为例,指出原始数据约512GB,而PQ码仅8GB,但实际内存还包括id、倒排列表偏移、分配器元数据,以及可选的原始向量和重排存储。工程中若只按PQ码估算内存,容易低估总占用。因此选型时应分项列出raw、code、id、centroid和list元数据,再决定是否分片或外置原始向量。

MSE与召回:不是一回事

实验显示,M8x4比M4x6多1字节,MSE更高但召回反而更好;同为4字节的M4x8与M8x4,M4x8两项都更优。这说明量化误差小不等于排序错误少,因为ADC距离估计存在交叉项偏差。因此调参时不能只看MSE,必须用验证集实测recall@k,并关注码长、子空间切分对排序的影响。

nprobe调参:先升后平

固定residual IVF-PQ为M8x6时,nprobe从1增至64,召回从0.4460升至0.5025后进入平台,全扫描时召回仍只有0.5025。前半段受IVF候选截断限制,后半段受PQ量化误差限制。因此调参应扫描nprobe并绘制召回-候选数曲线,若平台期召回不足,需考虑更长码、OPQ或重排,而非继续增大nprobe。

选型边界:压缩换容量

IVF-PQ适合原始向量或图索引放不进内存、且能接受用召回换成本的场景,但需要验证集调参和重排策略。HNSW则以内存换高召回和较少调参。两者并非替代关系,大系统常组合使用,例如HNSW作粗量化器、PQ存压缩向量、再从SSD加载原文精排。选型时应按内存、召回SLA和更新方式分配预算。

❓

Q&A

乘积量化(PQ)是如何压缩向量的?

PQ将D维向量切分成M个子空间,每个子空间维度为D/M,然后对每个子空间独立训练K类k-means码本。编码时,每个子向量只保存最近centroid的编号,因此一个向量被压缩成M个短码。若K=256,每个编号占1字节,总码长为M字节。

ADC和SDC在距离估计上有什么区别?

SDC(对称距离计算)将查询和数据库向量都量化,误差来自两边;ADC(非对称距离计算)保留查询的原始float32,只量化数据库向量,通过预计算查找表(LUT)来估计距离。ADC通常更准确,因为查询未被量化。

IVF-PQ中的nprobe参数如何影响召回率?

nprobe是查询时探测的粗聚类中心数量。增大nprobe会扫描更多倒排列表,召回率先上升,但随后进入平台期,因为剩余误差来自PQ量化。例如在实验中,nprobe从1增加到64,召回率从0.4460升至0.5025后不再提升。

为什么IVF-PQ通常对残差进行编码?

残差是原始向量减去其所属粗聚类中心后的向量。残差分布通常比原始向量更集中,因此PQ能用更短的码更好地拟合,降低量化误差。查询时也使用相对于同一粗聚类中心的查询残差来估计距离。

OPQ是如何改进乘积量化的?

OPQ(Optimized Product Quantization)学习一个正交变换R,在旋转后的空间训练PQ,以最小化量化失真。它不改变码长,而是通过优化子空间分解来降低重构误差,从而可能提升召回率。

在工程中部署IVF-PQ需要注意哪些陷阱?

常见陷阱包括:使用默认nprobe=1导致召回低;只报告QPS不报告召回和候选数;内存估算忽略id、倒排列表等开销;训练集偏离线上分布;忘记归一化导致度量混乱;nlist过大导致list过短。应使用验证集调参,并报告召回率、候选数和字节数。

🏷️

标签

➡️

继续阅读