《Embedding-based Retrieval in Facebook Search》论文精读

阿泽的学习笔记

共 1738字,需浏览 4分钟

 ·

2021-12-13 17:57

https://arxiv.org/pdf/2006.11632.pdf


EBR算是很经典的一篇工业界论文,是facebook发表在KDD2020上的一篇关于搜索召回的paper。这篇文章提到的大多trick对于做过召回的同学比较熟悉了,可贵之处在于全面,包括了特征、样本、模型、全链路等各种细节知识,本文尽量会把一些关键但容易忽视的点强调一下,介于个人水平问题难免有不准确的表述,欢迎留言讨论。(本文提到的各种结论都只可作为参考,不同的业务和数据可能会有不同的结论)

1. 整体思路与框架

本文的出发点是搜索只做到query关键词匹配的程度是远远不够的,还要结合用户信息及上下文提供个性化搜索服务,比如一个热爱数码的大学生农村卖水果的果农搜索【苹果】得到的结果应该分别是手机水果

通常的搜索分为召回和排序两个阶段,基于embedding的语义召回主要在第一阶段,它要解决的问题是如何从千万个文本中找到相关的topK个,难点一个是【准】,一个是【快】,准要求和用户+query高度的匹配,快要求从海量候选中搜索的延时低。

模型是双塔模型,当然这里做了一些特征和样本的trick,后面会提。整个架构如下:

  • 左边采用了query understanding+embedding inference两部分,即向量表征是补充而非替换

  • 在构建index时采用了embedding quantization

  • retrieval包括NN operator和Boolean Match

评估的时候为了快速迭代验证,采用了离线topk命中作为评估。我个人认为从召回的本质出发,本就没办法离线去准确评估一个召回的价值,当然迫于迭代效率+搜索场景,这个指标阐述一些feature的价值是可以接受的。下面就围绕这个指标的提升,阐述一下本文的各种工业界trick经验总结

2. 模型

模型结构就是双塔,特征也贴出来了

2.1 损失函数

本文将搜索相关性以pair-wise的角度建模,采用的是triplet loss,形式如下

margin是很重要的,说白了这个参数是划分样本难度的,如果特别大没办法收敛,如果特别小又没区分度,虽然对于m本文没讲怎么设置,但是讲述了负例采样数n应该设置为top-K=N/n,其实也容易理解,既然召回本质上是去全量候选中选topk,那么训练的时候一个正样本对应n个负样本如果能对齐这个比例就很好,当然现实中因为资源的问题很难如此对齐。

2.2 正负样本选取

召回正负样本选取之前也写过一次iwtbs:召回模型中的负样本构造,本文依旧是这个结论:

  • 【正样本】点击样本 > 展现样本

  • 负样本】随机负采样 > 展现未点击

当然本文详细讲述了hard mining的一些尝试,按照正负例分别介绍下:


hard negative mining

随机负采样难免导致样本太简单,虽然简单负样本已经证明了对召回的效果提高有用,但是总不能全都太简单了吧,所以总要挖掘少数介于简单和困难之间的负例,让模型感受世界的参差,不能只识别出来我不喜欢看美妆美食 喜欢看篮球,还要能识别出来我喜欢看湖人队还是篮网队,其中前者就是随机负采样干的事情,而后者就主要靠hard mining提供了。

本文提出了online和offline两种mining方式

  • online:在线一般是batch内其他用户的正例当作负例池随机采,本文提到选相似度最高的作为hard样本,同时强调了最多不能超过两个hard样本。

  • offline:在线batch内池子太小了不一定能选出来很好的hard样本,离线则可以从全量候选里选。具体做法是对每个query的top-k结果利用hard selection strategy找到hard样本加入训练,然后重复整个过程。这里提到要从101-500中采,太靠前的也许根本不是hard负例,压根就是个正例。以及两个很好的经验,第一个是样本easy:hard=100:1,第二个是先训练easy再训练hard效果<先hard后easy


hard positive mining

本文认为有一些用户未点击但是也能被认为是正样本,做法就是从日志中挖掘潜在的正样本,这也能解释为什么上面hard负样本是101-500了,因为这里可能1-10就是正样本了。

2.3 模型融合

本文提到采用不同正负样本比例训练出来的模型具有不同的优势,具体融合的方式有并行和串行两种。

  • 并行就是加权求和。为了能够使用FAISS,必须将多个模型产出的embedding融合成一个向量,将权重乘item embedding然后将各个模型产出拼接起来。

  • 串行就是先A模型后B模型,相当于召回拆成了两段。

串行这块我倒是觉得没啥意义,极端点你把负样本改成真实展现未点击那不就是个小精排,在召回搞个两阶段当然离线测出来有效果;并行做过多兴趣召回的能get到点,我觉得也是相同的底层思想。本文结论是使用挖掘出来的hard negative训练出来的hard model,效果比曝光未点击更好。

3. 特征

本文主要介绍了三个特征,分别是文本、地域、社交特征,当然线上我猜肯定还有很多好用的特征不方便写出来。

  • text features

主要对比了word n-gram和character n-gram,然后结论是character级别的更好,毕竟character量级更少,泛化也更容易,本文提到在character基础上增加word表征能提高效果。

  • location features

位置特征很好理解,这里的关键点在于query和doc端都要增加这个特征

  • social embedding features

可以理解为搞了一个单独的嵌入模型学习社交表征emd作为特征,具体怎么构建方法很多,最简单的比如搞个图deepwalk,推荐里面经常会有各种信息表征的向量作为特征,比如多模态  embedding就是大家都比较熟悉的

4. 索引

这块可能对于大多数人比较陌生,一般我们说召回用双塔结构主要优势就是在serving时可以快速响应,训练的时候user embedding和item embedding点积越大说明相似度越高,这样可以把所有候选item embedding离线构建索引,线上只需要计算user embedding然后近邻查找即可,最终都是查找精度和速度的trade off。

本文主要提到了比如ivf、PQ等关键词,这里简单介绍一下,Int8/float/PQ是常见的量化方法,主要目的是降低内存带宽和存储空间;而IVF/BF/HNSW则是检索算法,目的是提高检索的速度和精度。我们当然是希望存储小精度高,但这往往是相反的,所以根据自己候选量+精度对推荐效果的影响权衡一下,本文也提到了一些trick,比如聚簇个数、product quantization算法选择等问题,这种serving效果在大厂里工程团队基本都定制优化了,大致了解一下即可。

本文提过但是容易被忽略的一个点在于,全量候选构建索引是非常耗存储和费时的,所以facebook在构建索引的时候,只选择了月活用户、近期/热门的item,即部分query不会触发EBR,推荐场景同理,根据自己的召回目标搞合适的候选往往对于部分分层有奇效。

5. 全链路优化

之前写召回的文章也提到优化一定是全链路才能发挥最大的效用,本文也秉承着这个思想对于召回外的相关优化进行了阐述。

  • 将embedding作为排序模型的特征。如果不太了解思想的可以读一下《Deep Match to Rank Model for Personalized Click-Through Rate Prediction》,简单来讲就是给排序模型透穿召回信息,同理给召回透传排序的信息提升排出率也是常规操作。至于这里具体是怎么做的没有太详细的讲,常见的问题比如end2end还是拆开、多目标排序怎么搞、多路召回怎么透传都可以根据自己的系统架构设计。

  • 训练数据反馈循环。 向量表征一般召回率不错但是精度一般, 为了提高精度,本文搞了一个人工评分反馈流程, 记录结果并后将这些结果发送给运营标记是否相关,在原本的基础上叠加这些人工评分数据来重新训练相关性模型。这个也很好理解,相当于补充了一些更准的训练数据,当然现实里有没有这么多人力去搞,推荐问题有没有搜索相关性这么好定义label就是另一回事了。



【总结】

本文有一些经验值得借鉴和思考,但比起结论更重要的是思维的方法,比如为什么要做hard mining,自己的场景哪些数据值得hard mining,自己系统中召回问题最关键的是样本、架构还是数据流,只有先定义了问题才能做ROI最高的优化。


浏览 43
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报