ScaNN进行高效检索服务(TensorFlow 构建推荐系统)
什么是 ScanNN?
ScaNN
是可扩展最近邻的缩写。在推荐系统的检索阶段,我们需要快速找到给定查询嵌入的最近数据集的嵌入。通常嵌入集对于穷举搜索来说往往太大。因此,需要像ScaNN
这样的工具来进行近似邻域搜索。ScaNN
于2020.06
开源。他提供高效的向量相似性搜索,即从海量数据库中快速地匹配和检索相似项。他包括基于树的空间分区、非对称哈希、内涵和倒排索引等实现。由于这些高度优化的算法,ScaNN
在大型和中等规模数据库的最近邻搜索方面提供了显著的加速。
构建ScanNN支持的模型
为了在TFRS
中尝试ScaNN
,我们将构建一个简单的MovieLens
检索模型。
1 | import os |
评估近似值
当使用近似前K
个检索机制(例如ScaNN
)时,检索速度通常是以牺牲准确性为代价的。为了理解这种权衡,在使用ScaNN
时测量模型的评估指标并将其与基线进行比较非常重要。幸运的是,TFRS
让这一切变得简单。我们只需使用ScaNN
的指标覆盖检索任务的指标,重新编译模型并运行评估。为了进行比较,我们首先运行基线结果。仍然需要覆盖我们的指标,以确保它们使用扩大的候选集而不是原始的电影集:
1 | # Override the existing streaming candidate source. |
这表明在这个人工数据库上,近似值几乎没有损失。一般来说,所有近似方法都表现出速度与精度的权衡。要更深入地了解这一点,您可以查看Erik Bernhardsson
的ANN
基准。
部署近似模型
1 | # 我们可以将其保存为SavedModel对象 |
生成的模型可以部署在安装了TensorFlow
和ScaNN的``Python
的服务器中提供服务。您还可以从Dockerfile
自行构建映像。
调整ScaNN
现在让我们研究一下调整ScaNN
层以获得更好的性能/准确性权衡。为了做到这一点,我们首先需要测量我们的基线性能和准确性。从上面来看,我们已经测量了模型处理单个(非批量)查询的延迟。现在我们需要研究ScaNN
的准确性,我们通过召回来衡量它。让我们计算当前ScaNN
搜索器的召回率。首先,我们需要生成brute force
、ground truth top-k
:
1 | # Process queries in groups of 1000; processing them all at once with brute force |
为此,我们需要一个模型来说明ScaNN
的调节旋钮如何影响性能。我们当前的模型使用ScaNN
的tree-AH
算法。该算法对嵌入数据库(“树”)进行分区,然后使用AH对这些分区中最有希望的进行评分,AH
是一种高度优化的近似距离计算例程。TensorFlow Recommenders
的ScaNN Keras
层的默认参数设置num_leaves=100
和num_leaves_to_search=10
。这意味着我们的数据库被划分为100
个不相交的子集,并且这些分区中最有希望的10
个用AH
进行评分。这意味着10/100=10%
的数据集正在使用AH
进行搜索。
例如,如果num_leaves=1000
且num_leaves_to_search=100
,我们还将使用AH
搜索数据库的10%
。然而,与之前的设置相比,我们要搜索的10%
将包含更高质量的候选者,因为更高的num_leaves
允许我们对数据集的哪些部分值得搜索做出更细粒度的决策。当num_leaves=1000
和num_leaves_to_search=100
时,我们获得了更高的召回率:
1 | scann2 = tfrs.layers.factorized_top_k.ScaNN( |
一般来说,调整ScaNN
搜索就是选择正确的权衡。每个单独的参数更改通常不会使搜索更快、更准确;我们的目标是调整参数在这两个相互冲突的目标之间进行最佳权衡。在我们的例子中,scann2
相对于scann
显着提高了召回率,但付出了一定的延迟代价。我们能否调低一些其他旋钮来减少延迟,同时保留我们的大部分召回优势?让我们尝试使用AH
搜索数据集的70/1000=7%
,并且仅对最后400个候选者重新评分:
1 | scann3 = tfrs.layers.factorized_top_k.ScaNN(model.user_model,num_leaves=1000,num_leaves_to_search=70,num_reordering_candidates=400) |
这些旋钮可以进一步调整,优化accuracy-performance pareto frontier
的不同方面。ScaNN
的算法可以在范围更广的召回目标上实现最优的性能。ScaNN
使用先进的矢量量化技术和高度优化来实现。