内容提要
Qdrant向量数据库通过量化与重打分机制应对向量集合超出内存的情况:量化在内存保留压缩副本,原始向量移至磁盘;TurboQuant通过旋转向量均匀分布误差,bits4为常用默认值;重打分读取原始向量修正压缩误差,但增加磁盘读取开销。测试表明,1比特量化配合重打分和过采样可将召回率从0.605恢复至0.951,接近float32基线。建议固定量化副本、原始向量冷存储,并启用io_uring异步读取。
延伸解读
量化与数据类型:内存策略的本质区别
文章指出,量化在内存中保留压缩副本,原始向量移至磁盘;而使用float16等低精度数据类型则直接改变原始向量本身。这一区别决定了是否还有全精度向量可用于重打分。若采用数据类型转换,原始向量已被替换,重打分将失去基准;而量化保留了原始向量,使重打分能修正压缩误差。因此,在内存不足时,量化配合重打分是更可控的方案。
重打分的代价:磁盘读取成为瓶颈
测试显示,当原始向量驻留内存时,重打分几乎不增加延迟(12 GiB限制下仅增加0.3毫秒);但当内存受限(4 GiB),重打分需要从磁盘重新读取原始向量,延迟从约4毫秒飙升至43毫秒,读取量从0.30 GB增至2.98 GB。这表明重打分的开销主要来自磁盘I/O,而非评分计算。将原始向量设为cold或cached对中位数延迟影响不大,因为读取无法避免。
1比特量化的召回恢复:重打分与过采样的作用
1比特量化在不重打分时召回率仅0.605,远低于float32的0.957。启用重打分后,召回率跃升至0.951,接近基线;过采样从1提高到4,召回率进一步升至0.988,但额外收益有限。文章建议,在bits1下,一次重打分已恢复大部分质量,过采样超过1主要增加磁盘读取,需权衡召回与延迟。
部署建议:固定量化副本,原始向量冷存储
Qdrant建议将量化副本固定(pinned)在内存,原始向量设为cold,以缩小内存占用并保持搜索速度。同时,启用io_uring异步读取可并行处理冷数据的重读,降低延迟。但需注意,io_uring默认关闭,仅适用于冷结构,且需要Linux内核支持。在混合搜索中,稀疏向量索引默认固定,可能占用量化副本所需内存,需显式设置放置策略。
Q&A
当向量集合超出内存时,Qdrant 如何让搜索仍然可用?
Qdrant 在内存中保留每个向量的压缩副本,并将全精度原始向量移至磁盘。查询时先在压缩副本上预取候选,再通过重打分读取原始向量修正误差。
TurboQuant 量化中的 bits 参数应该从多少开始设置?
建议从 bits4 开始,这是许多工作负载的良好默认值,可实现八倍压缩。
重打分(rescore)和过采样(oversampling)在查询中起什么作用?
重打分在密集预取后读取原始向量,按全精度分数重新排序候选;过采样决定预选多少候选进行重打分。两者都是查询参数,可随时调整而不影响集合。
1 比特量化在开启重打分和过采样后,召回率能恢复到什么程度?
1 比特量化在不重打分时召回率仅 0.605,开启重打分和过采样 1 后提升至 0.951,过采样 4 可达 0.988,接近 float32 基线 0.957。
如何通过内存放置(memory placement)优化超出内存的集合性能?
将量化副本设为 pinned 固定在内存,原始向量设为 cold 惰性从磁盘加载。这样可缩小内存占用并保持搜索速度,同时启用 io_uring 异步读取可降低冷读开销。
重打分在原始向量不在缓存时对查询延迟影响有多大?
当原始向量在缓存中时,重打分几乎不增加延迟(12 GiB 限制下仅增加 0.3 ms);当原始向量不在缓存时,重打分成为查询最慢的部分,4 GiB 限制下增加 39.1 ms,因为需要重新读取原始向量页。
除了 TurboQuant,Qdrant 还支持哪些量化方法?各自适用场景是什么?
Qdrant 还支持 Scalar Quantization(将向量分量转为 int8,适合中等压缩)、Binary Quantization(紧凑快速,适合高维中心化分布嵌入)和 Product Quantization(优先减小内存占用,但精度和速度权衡更大)。
如何在自己的集合上验证量化配置是否合适?
先对代表性查询样本计算精确的密集 top k,然后运行现有密集预取并改变 rescore 和 oversampling 变体,用 Recall@k 对比精确结果。若有标签,再比较最终 nDCG@k。