向量量化(Vector Quantization)是一种数据压缩技术,旨在减小高维向量的存储空间,同时尽可能保留重要信息。在处理由OpenAI等嵌入模型生成的1536维向量时,单个向量需6KB内存;100万个向量则需约6GB。随着数据集增长至数百万向量,内存和计算需求急剧增加。向量量化通过压缩向量尺寸,有效降低内存占用并加速搜索操作。
HNSW索引的挑战
HNSW(分层可导航小世界)索引通过分层图结构连接每个向量到其最近邻。插入新向量时,系统需确定其在图中的位置,类似搜索过程。这导致随机读取和顺序遍历的高成本,尤其在高维向量数量庞大时更为显著。量化通过压缩向量,使得这些操作更加高效。
标量量化(Scalar Quantization)
在Qdrant中,每个维度默认用float32表示(4字节)。标量量化将向量值映射到int8范围(1字节,表示256个值),实现75%的内存缩减。例如,[-1.0,1.0]范围内的值被线性映射到int8的[-128,127]。配置时需在创建集合时添加quantization_config,其中quantile参数(如0.99)排除最极端的1%值,以平衡精度。标量量化在提升速度和压缩的同时,精度损失最小,适合大多数应用。
二进制量化(Binary Quantization)
二进制量化将向量转换为二进制表示(0或1),值大于零为1,否则为0。对于1536维向量,内存从6KB降至192字节,实现32倍压缩,且搜索速度可提升40倍。Qdrant自动在索引过程中执行二进制量化。此方法依赖优化的CPU指令(如XOR和Popcount)进行快速距离计算。兼容模型包括OpenAI text-embedding-ada-002和Cohere embed-english-v2.0,建议至少1024维以获得良好精度。虽然速度极快,但精度和模型兼容性需通过过采样和重打分技术来维持。
乘积量化(Product Quantization)
乘积量化通过将高维向量拆分为子向量,并为每个子向量建立码本(codebook)实现压缩。码本中的中心点通过K-means聚类(K=256)确定。1024维向量原占4096字节,经乘积量化后仅需128字节(128个索引,每个1字节),压缩比最高可达64倍。配置时需指定压缩率(如x32)。需注意,高压缩比可能导致精度下降,适合内存优先且精度容忍的应用。
重打分、过采样与重排序
为弥补量化带来的精度损失,Qdrant支持过采样和重打分。首先使用量化向量进行初始搜索,通过过采样(如限制为4时,采样因子2则检索8个候选)扩大候选集。然后利用原始向量对候选集重打分,计算更精确的相似度。最后重排序确定最终top-K结果。这些技术可在保持速度的同时提升准确性。
磁盘与内存的资源分配
默认情况下,原始向量和量化向量均存储在RAM中。为节省内存,可将原始向量移动至磁盘(on_disk=True),仅将量化向量保留在RAM。例如,配置binary quantizer并设置original vectors on_disk后,RAM仅存储量化向量,大幅降低成本。注意,需显式设置on_disk=True才能获得RAM节省。
使用io_uring加速重打分
在Linux系统上,io_uring技术允许并行处理多个磁盘操作,显著降低I/O开销,尤其在重打分阶段需频繁读取原始向量时。Qdrant通过配置storage: async_scorer: true启用io_uring。这能有效提升磁盘上大规模数据集的搜索性能。
性能对比与切换方法
Qdrant默认使用量化向量进行搜索。可通过设置ignore: true临时禁用量化,比较结果差异。用户可随时修改或移除量化配置,而不影响原始向量。例如,从标量量化切换为二进制量化,或完全禁用量化。
总结
三种量化方法各有优劣:二进制量化速度最快、最省内存,但需兼容模型;标量量化精度损失小,是安全的默认选择;乘积量化压缩比最高,但精度和索引速度稍逊。根据应用需求,结合过采样、重打分和io_uring等技术,可在速度、精度和成本间取得理想平衡。