Puck 是百度自研的高性能 ANN 检索引擎,名称取自经典 MOBA 游戏 DOTA 中的智力英雄 - Puck,是飘逸、灵动的代表。ANN 全称近似最近邻检索(Approximate Nearest Neighbor),目标是从全量向量数据中寻找距离最近的 TopK 个向量,同时需要平衡检索效果和检索成本。
在工业应用场景中,有限的内存、昂贵的计算机资源和不断增大的数据库规模对于所有搜索应用来说都同样重要。随着检索业务服务的快速发展,对高检索延迟和珍贵但有限的资源提出了更高的要求,Puck 的诞生正是为了满足这种需求。
Puck 开源项目包含两种百度自研的检索算法 Puck&Tinker,该项目用 C++ 编写,并有 python3 封装。
Puck 是一种针对大规模数据集的高效方法,在 NeurIPS'21 赛道的多个 1B 数据集中表现最佳。此后,Puck 的性能提高了 70%。Puck 包括反转索引和数据集多级量化的两层架构设计。如果内存会成为瓶颈,Puck 可以解决你的问题。
Tinker 是一种针对较小数据集(如 10M、100M)的有效方法,在 big-ann-benchmarks 中比 Nmslib 具有更好的性能。Thinker 比 Puck 消耗更多内存,但性能比 Puck 更好。如果你想要更好的搜索性能并且不需要关心内存使用,Tinker是更好的选择。
Puck 支持余弦相似度、L2(Euclidean) 和 IP(Inner Product, conditioned)。当两个向量归一化时,L2 距离等于 2 - 2 * cos。IP2COS是一种将IP距离转换为cos距离的变换方法。搜索结果中的距离值始终为L2。
Puck 使用压缩向量(PQ 之后)代替原始向量,默认情况下,内存消耗仅为原始向量的 1/4。随着数据量的增加,Puck的优势更加明显。Tinker需要保存相似点的关系,默认情况下内存消耗比原始向量多(小于Nmslib)。基准测试中的更多性能细节。参阅此自述文件以了解更多详细信息。
Puck 的优势
- 易用性:提供简单易用的 API 接入,尽量少的暴露参数,大部分参数使用默认即可达到良好性能。
- 扩展性:采用完全自研的索引结构,支持多种功能扩展,适应多种场景,项目模块划分合理,便于改造优化,可方便用户接口自行添加。
- 高性能:在 benchmark 的千万、亿、十亿等多个数据集上,Puck 性能优势明显,均显著超过竞品。
- 可靠性:经过多年在实际大规模场景下的验证打磨,广泛应用于百度内部包括搜索、推荐等三十余条产品线,支撑万亿级索引数据和海量检索请求。
Puck 功能拓展
- 实时插入:支持无锁结构的实时插入,做到数据的实时更新。
- 条件查询:支持检索过程中的条件查询,从底层索引检索过程中就过滤掉不符合要求的结果,解决多路召回归并经常遇到的截断问题,更好满足组合检索的要求。
- 分布式建库:索引的构建过程支持分布式扩展,全量索引可以通过 map-reduce 一起建库,无需按分片 build,大大加快和简化建库流程。
- 自适应参数:ANN 方法检索参数众多,应用起来有不小门槛,不了解技术细节的用户并不容易找到最优参数,Puck 提供参数自适应功能,在大部分情况下使用默认参数即可得到很好效果 。
评论