方法原理
IVF
原理:使用聚类方法减少搜索范围
流程
训练:将库向量进行128个(K个)聚类,保存聚类中心和每个类中的向量
预测:将预测向量与128个聚类中心对比,找到所属聚类中心,只在同类的库向量中进行查询
预测计算开销
K次(D维)
每个预测向量与K个聚类中心进行相似度计算,原向量维度128维(D维)
PQ
原理:使用聚类方法优化距离计算
将每个向量切分成4组(M组)向量,对每组进行聚类,利用聚类中心来代替库向量的位置
计算查询向量与所有聚类中心的距离,利用查表方法来代替计算向量距离
流程
训练:将库向量进行4组(M组)切分,每组进行256个(作者经验值)聚类,保存每个库向量的4个聚类中心编号
预测:
将预测向量切分成4组,每组与所有256个聚类中心计算距离,保存每个聚类中心编号对应的距离(称为距离池)
遍历所有库向量,利用查表的方法,查询4组对应的距离,求和作为预测向量与库向量的距离
对距离进行排序,如果需要计算cos相似度,可以取top5的库向量,再计算cos相似度
预测计算开销
距离池:256次4组(D/4维)
查表:库向量4组
与Lsh对比
方法的不同
Faiss中的PQ使用与聚类中心的距离代替实际距离
PQ没有像Lsh一样将聚类中心作为Hash,PQ的子空间太小。
假设使用上文中的维度,IVF为1024个聚类,PQ共4组256个聚类,一共有1024 *(256)^ 4,即2^42
个子空间,约为40千亿个子空间。而Lsh如果使用十个plane,只有2^10为1024个子空间。假如库向量有1万个,Faiss的子空间平均分不到一个向量。
Faiss中的IVF使用了Hash,PQ使用了遍历
Lsh中也是使用了Hash,也进行了遍历,但Lsh使用了多组Hash
Faiss中计算cos距离
先使用PQ距离计算top5,然后再计算cos距离,这样可能又会丢失了一些实际cos距离较小的点
计算开销对比(预测)
Faiss每个查询固定计算开销,与库向量大小无关(只有查表有关),每条查询 K + 256*M
假设查询每天4w条新闻去重,K = 1024, M = 4,计算开销 = 4w * 2048
Lsh每个查询与每个子空间平均保存的库向量数量有关,每条查询 16组 * (10次hash + 库向量/1024子空间)
假设查询每天4w条新闻去重,计算开销 = 4w * 16 *(10 + 4w/1024) = 4w * 800
可见小规模语料上,Lsh计算开销更低
效果的差异
Faiss中的IVF和Lsh的Hash一样,都是进行了1024个子空间的聚类
都减少了召回
Faiss中PQ使用PQ距离(且用聚类中心代替库向量),再topN进行cos计算
没有实际使用cos,比Lsh减少了召回
IVF没有使用多组向量,而Lsh使用了16组,来增加召回
可见Faiss的召回会低于Lsh
综上,效率上,Faiss适合大规模库向量的查找,Lsh适合小规模的查找,效果上,Faiss召回比Lsh低