向量检索服务迭代演进

背景

在搜索推荐系统里,有一个重要的服务是向量检索服务,也就是求向量在空间中最相近的topk个向量,在搜索系统里,涉及大量的召回引擎可能需要用到向量检索服务,需要在线实时计算,并且可快速响应;

所以这里需要解决两个问题,一个是存储所有待计算的向量,并对输入的向量,做向量相似度计算,求得最近的向量列表排序,取得top k个;另一个因为要达到在线服务即时响应需求,因为这个是基础服务,所以要做到毫秒级别响应

解决方案&迭代演进

1、最粗暴的向量KNN计算

对输入的向量,遍历待计算的所有向量做相似度计算,再用有限容量K最大堆排序,取得最后topk向量;

优点是:算法实现简单,服务维护成本低;针对向量数量小的,在万级别的情况下,也可以达到毫秒级响应;

缺点:面向十万级别以上向量,每一次的请求计算量一样,都要做全量计算,计算代价太大,响应性能不能满足;

2、引入HNSW java开源算法库

对向量做索引,主要索引存储在内存里,提高响应速度,针对大数据量的向量可快速响应;

优点:直接用java服务开发管理向量,向量的更新管理,直接内嵌在服务里,不需要再增加多一层请求服务。管理简单,实现成本 也不高;

存在风险问题: 因为索引放在内存里,要占用比较多的内存资源 ,特别是数据量较大的情况下,内存占用太大,400W左右的数据量大概占用10G左右;

索引更新,直接在线上构建,占用cpu使用,索引更换过程时,需要双倍内存资源,更新索引时候容易发生fullgc,导致其它响应问题;

3、引用hnsw c++开源算法库,离线索引&分布式索引构建

采用c++实现库索引则使用了堆外内存,减少gc,并且利用c++对密集计算性能的优势,提高响应性能;

针对大数据量向量,拆分多分片,除了支持更大数据量,增加并行计算提高响应速度;

  • 索引也会先在离线建完,序列化持久到文件,线上直接加载索引文件反序列化再提供服务;

  • 更新索引虽然占用双倍内存,但使用堆外内存,避免引起FULLGC风险问题,只要机器预留一定的内存资源足以;

  • 分布式索引,支撑索引数据量是单机n倍,并提高并行计算,提高响应性能;

存在的问题点:

  • 分布式管理 会比原有单点管理 复杂性变大,系统的开发成本与维护成本 也会相应增加;

  • 现有的hnsw实现里有两块占用比较大内存,label 与内部id映射,向量的存储。可考虑转移到外存,减少内存消耗;

4. 基于第3种方案,再优化了一版,修改了hnsw源码,将id->vector , label->id对应的数据结构移到外存上,减少依赖的内存资源;

优化点:比前一版,可以将部分内存资源转移到外存,减少资源成本 ;

存在问题点: 修改了源生代码 ,并且多了一个RocksDB外存管理 ,整体依赖的技术栈也增加,复杂度也会因此增加。

未来展望

hnsw索引目前遇到一个相似度计算问题,不能比较好支持点乘相似度计算,所以还是得再换用fasis,它支持比较多种类型的索引,以及相似度计算也支持比较多类,比较能满足需求;可以在现有的架构上,改用fasis接入替换hnsw;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值