乔纳森·卡茨:用于pgvector向量搜索和存储的标量和二进制量化

💡 原文英文,约5000词,阅读约需19分钟。
📝

内容提要

本文讨论了在PostgreSQL中使用标量和二进制量化技术进行向量搜索和存储的方法。标量量化可以减小向量维度的大小,而二进制量化将维度减小为一个比特位。文章提供了实现这些技术的示例,并评估了它们对索引构建时间、查询性能和召回率的影响。结果显示,使用2字节浮点数的标量量化是明显的优选,既提供了空间和时间的节省,又不损失性能。二进制量化也可以有效,但其对召回率的影响取决于向量的多样性。总体而言,有效的量化技术可以减小存储和内存占用,实现向量工作负载的可扩展性。

🔎

延伸解读

标量量化:空间与时间双赢

测试表明,将4字节浮点向量量化为2字节浮点(halfvec)后,索引大小减少1.45至3倍,构建时间缩短1.06至3.17倍,而召回率几乎不变,查询性能略有提升。这得益于更小的数据类型允许每个索引页存储更多向量,减少I/O。对于高维向量(如960维、1536维),效果尤为明显。因此,在pgvector中优先尝试halfvec索引是合理的起点。

二进制量化:存储极致但召回风险高

二进制量化将每个维度压缩为1比特,索引大小可减少16至19倍,构建速度提升1.6至4.6倍。然而,召回率严重依赖向量的比特多样性:在gist-960数据集上召回率为0%,sift-128仅2.5%,而dbpedia-openai-1000k达到68.6%。因此,二进制量化必须配合重排序(rerank)使用,且适用于高维、多样性好的向量。若召回不达标,应回退到标量量化或全精度向量。

重排序:二进制量化的必要步骤

使用二进制量化时,直接搜索返回的结果可能毫无意义。通过重排序,即先用二进制索引快速筛选候选集,再用原始全精度向量计算距离并重新排序,可以显著提升召回率。例如,在dbpedia-openai-1000k数据集上,重排序后召回率从68.6%提升至99.8%,同时查询吞吐量(QPS)提升1.42倍,p99延迟降低33%。但重排序会增加查询开销,需在召回率和延迟之间权衡。

实践建议:根据场景选择量化

对于大多数工作负载,标量量化(halfvec)是安全且高效的选择,能在几乎不损失召回率的情况下减少存储和构建时间。二进制量化则适用于向量维度高、比特多样性好且能接受重排序开销的场景,可大幅降低内存占用,使索引能完全放入内存。但需注意,二进制量化的召回率可能随数据集增大而下降,因此务必在实际数据上测试召回率和性能,再决定是否采用。

❓

Q&A

什么是标量量化和二进制量化?

标量量化是将向量维度减少为更小的数据类型,而二进制量化则将维度减少为单个比特位。

pgvector 0.7.0版本新增了哪些量化功能?

pgvector 0.7.0版本支持标量和二进制量化,允许索引2字节浮点数和比特向量。

标量量化对查询性能有什么影响?

使用标量量化时,查询性能和召回率几乎与原始向量相同,且能显著节省空间和构建时间。

二进制量化的优缺点是什么?

二进制量化在存储效率上表现优异,但可能导致召回率下降,尤其是在向量多样性不足时。

如何使用标量量化创建索引?

可以通过在PostgreSQL中使用表达式索引,将向量转换为2字节浮点数来创建标量量化索引。

量化技术如何影响向量存储的可扩展性?

有效的量化技术可以减少存储和内存占用,从而实现向量工作负载的可扩展性。

🏷️

标签

➡️

继续阅读