课程合集:ShusenWang的个人空间-ShusenWang个人主页-哔哩哔哩视频 (bilibili.com)
课件地址:GitHub - wangshusen/SearchEngine: 搜索引擎原理
目录
概要
1、搜索引擎的基本概念
曝光和点击
垂搜vs通搜
课程安排
2、决定搜索满意度的因素:相关性、内容质量、时效性、个性化
相关性(Relevance)
内容质量
时效性
个性化
3、搜索引擎的评价指标
北极星指标:用户规模&留存
中间指标:用户的点击等行为
人工体验评估
4、搜索引擎的链路:查询词处理、召回、排序
查询词处理
分词(Tokenization)
词权重(目的是丢词)
类目识别
查询词意图识别
查询词改写
召回(Information Retrieval)
文本召回(借助倒排索引)
向量召回(双塔模型)
KV召回(作为补充)
排序(Ranking)
相关性
1、定义与分档
相关vs不相关
档位细分
总结
标注流程
2、评价指标(AUC、正逆序比、DCG)
pointwise:AUC (离线)
pairwise:PNR (离线)
listwise:DCG (线上)
离线评价指标 (point&pair-wise)
线上评价指标 (listwise)
思考题:NDCG
3、文本匹配(TF-IDF、BM25、词距)
链路上的相关性模型
词匹配分数 (反映查询词和文档的相关性)
TF-IDF
BM25 (TF-IDF的变体)
词袋模型 (bag of words)
词距分数 (Term Proximity,从另一个角度反映相关性)
OkaTP (既考虑了词频,也考虑了词距)
4、BERT模型结构及线上推理
交叉BERT模型 (准确性好,但推理代价大)
分词粒度:字粒度 vs 字词混合粒度
推理降本
双塔BERT模型 (准确性不好,但推理代价小)
5、BERT模型的离线训练
训练相关性BERT模型
微调(fine tuning)
后预训练(post pretrain)
蒸馏(distillation)
为什么做蒸馏?
怎样做蒸馏?
一些有效的蒸馏技巧
总结
概要
1、搜索引擎的基本概念
查询词(query):用户在搜索框中输入的词
查询建议(SUG):在用户点击搜索之前,搜索引擎会给出很多相关词,如用户输入“深度学习”,SUG可能为“深度学习框架”、“深度学习教程”等等。作用是让搜索引擎用起来更方便
文档:即搜索结果,如网页链接(Google、百度)、商品(Amazon、淘宝)、视频(YouTube、B站)
搜索结果页:搜索完成的整个界面。搜索结果页的主体为文档,会有首图、标题、摘要等预览
标签/筛选项:搜索结果页中包含的信息,如最新(按时间)、最热(按点击&交互次数)、视频
文档单列曝光:搜索结果页每行只有一篇文档(Google、百度、YouTube)
文档双列曝光:搜索结果页每行有两篇文档(淘宝、京东、小红书),两者只是产品形态的差异,后台的搜索引擎算法和工程架构差不多
曝光和点击
曝光:用户在搜索结果页上看到文档,就算曝光。如屏幕上最多展示3篇文档,假如用户搜索之后不往下滑,那么只有前3篇文档获得曝光
搜索引擎考虑两类点击率:文档~、查询词~
文档点击:在曝光之后,用户点击文档,进入文档详情页
- 文档点击率:文档点击总次数 / 文档曝光总次数(独立看待每篇文档的点击),通常不高,10%左右
查询词点击:用户点击搜索结果页上任意一篇文档,就算“查询词点击”(用户点击一篇or几百篇文档,都只算一次查询词点击)。每次搜索,要么有查询词点击,要么没有查询词点击
- 查询词点击率(有点比):查询词点击总次数 / 搜索总次数,该值≤1,可以反映用户对搜索结果是否满意。70%左右
查询词首屏点击:用户点击搜索结果页首屏的任意一篇文档,就算“查询词首屏点击”
- 查询词首屏点击率(首屏有点比):查询词首屏点击总次数 / 搜索总次数,该值介于0-1之间,首屏有点比 < 有点比(因为 查询词首屏点击 比 查询词点击 更严格),60%左右。搜索排序做得好,首屏有点比就会高
有点比 重要性高于 文档点击率
垂搜vs通搜
1、垂直搜索(垂搜):针对某一个行业的搜索引擎
- 电商搜索:Amazon、淘宝、京东、拼多多
- 学术搜索:Google Scholar、知网
- 本地生活搜索:Yelp、大众点评、美团、饿了么
- 酒店机票搜索:Booking、美团、携程、东航
- 租售房搜索:Zillow、Redfin、Airbnb、贝壳
- 招聘搜索:LinkedIn、脉脉、Boss直聘
特点:
(1)垂搜的文档普遍是结构化的,容易根据文档属性标签做检索筛选
- 电商:商品,可以限定品牌、卖家、价格、颜色
- 学术:论文,可以限定关键词、作者、期刊、年份
- 本地生活:店铺,可以限定类目、商圈、距离
(2)垂搜用户的意图明确
- 大众点评用户搜索“寿司”,目的是找寿司餐厅
- 淘宝用户搜索“拳击”,目的是找拳击相关的商品
2、通用搜索(通搜):覆盖面广,不限于一个领域
- 例:谷歌、百度、必应、抖音(抖音可以自动判断查询词的意图,找视频/用户/商品/直播/本地生活的店铺)
特点:
(1)文档来源广,覆盖面大(网页、视频、图片、商品、直播、店铺)
(2)没有结构化,检索难度大(需要搜索引擎自己做网页分析抽取信息)
(3)用户使用通搜的目的各不相同,较难判断用户意图
本课程主要研究通用搜索
课程安排
基础知识:用户满意度、评价指标、搜索链路
相关性(影响用户体验最主要的因素):定义与分档、评价指标、文本匹配、语义匹配
搜索链路的三个环节:
- 查询词处理:分词、NER、词权重、类目、意图、改写
- 召回:文本召回、向量召回、离线召回
- 排序:排序模型、训练
查询词推荐/被动搜索(跟搜索链路是独立的):推词场景、推词召回、推词排序
需要具备以下知识基础:NLP&深度学习(尤其是Attention和BERT)、推荐系统的基础知识(AB测试、向量召回、排序模型、多样性算法)
2、决定搜索满意度的因素:相关性、内容质量、时效性、个性化
业界共识:相关性、内容质量、时效性是影响用户满意度的三大因素
移动互联网时代,个性化、地域性也会影响用户满意度
通用搜索引擎迭代优化的目标是让用户更满意:
- 如何让用户更满意?提升相关性、内容质量、时效性、个性化
- 如何评价用户体验?留存、有点比等客观指标;人工评估的主观指标
相关性(Relevance)
影响用户体验最重要的因素。查询词和文档在语义上有多相关,只是一个分数
定义:
- 相关性是 查询词q 与 文档d 两者的关系
- 相关性是客观标准,不取决于用户u,无个性化。如果大多数有背景知识的人认为 (q,d) 相关,则判定为相关
- 相关性是语义上的,不是字面上的。相关是指 d能满足q的需求 或 回答q提出的问题
- 查询词q可能有多重意图。只要d命中q的一种主要意图,则(q,d)算相关
模型:
- 召回、粗排、精排均需要计算相关性
- 召回完成之后,候选文档量级为数万;召回海选阶段用文本匹配分数(如tf-idf、类目匹配分数等)或双塔BERT模型粗略地估计相关性
- 粗排阶段候选文档量级为数千,用双塔BERT模型(推理代价小)或浅层交叉BERT模型计算相关性
- 精排阶段候选文档量级为数百,用交叉BERT模型(通常4层)计算相关性
内容质量
分为EAT、文本质量、图片质量等几类,每一类都有多种分数
(1)EAT(又被称为权威性):针对网站和作者,是谷歌提出的内容质量评价标准
- 专业性(Expertise):作者有专业资质,比如医生、记者等
- 权威性(Authoritativeness):作者、网站在领域内有影响力,不会被用户质疑
- 可信赖(Trustworthiness):作者、网站的名声好坏
对于 your money or your life 方面(金钱、健康类)的查询词,EAT是排序的重要因子
- Your money:
- 金融理财(保险、投资、报税、贷款、转账)
- 电商、购物
- Your life:
- 医疗健康(诊断建议、用药建议、医院介绍、减肥)
- 法律等严肃的主题(诉讼、移民、选举、离婚、收养)
- 对人生有重大影响的主题(高考、择校、出国、就业)
Google's Search Quality Evaluator Guidelines
(2)文本质量:针对文档本身。不是一个分数,而是很多个分数,在搜索排序中起作用
- 文字的质量:文章写得好不好?
- 文章的价值:文章是否清晰、全面,事实是否准确,信息是否有用
- 作者的态度和水平:写作是否认真,写作的专业程度,写作的技巧
- 文章的意图:有益、有害?
- 有益:分享有用的知识、攻略、亲身经历
- 有害:虚假信息、软广、散布仇恨、男女对立、发泄情绪
- 负面信号:标题党、图文不一致、虚假引流标签、堆砌关键词...
对于每个文本质量分数,都有一个专门训练的模型:
- 模型:BERT等NLP模型、CLIP等多模态模型。预训练后再用人工标注的数据做finetune
- 数据:制定分档规则,然后人工标注
- 文本质量分数都是静态的,只需计算一次。在文档发布或被检索时,用模型打分,分数存入文档画像(搜索排序时直接读取文档画像)
(3)图片质量(或视频质量):分辨率、有无水印、是不是截图、图片是否清晰、图片的美学...
总结:内容质量不是一个分数,而是很多分数,会在搜索排序中用到
时效性
意图分为突发时效性、一般时效性、周期时效性
文档的年龄(从文档发布/更新到现在过了多久)在排序中起多大作用?
- 时效性强需求:query = “最新房贷政策”、“美元汇率”
- 有时效性需求但不强:query = “泰国旅游”、“新荣记探店”
- 无时效性需求:query = “搞笑萌宠”、“宝宝湿疹”
=> 取决于查询词,查询词对时效的需求越强,文档年龄的权重就越大
- 优化搜索时效性的关键是识别查询词的时效性意图,即查询词对“新”的需求,即卡文档年龄
- 分类:突发时效性、一般时效性(强/中/弱/无)、周期时效性
- 识别方法:数据挖掘、语义模型
(1)突发时效性:查询词涉及突发的新闻、热点事件
- 如果查询词带有突发时效性,那么用户想看最近发布的文档
- 识别方法:以数据挖掘为主
- 挖掘站内搜索量激增的查询词
- 挖掘站内发布量激增的关键词
- 爬取其他网站的热词
- 为什么不能用BERT等自然语言模型?
- 人擅长判断文字质量、相关性,BERT也擅长
- 如果不借助新闻媒体,人无法判断突发时效性
(2)一般时效性:只看查询词字面就可以判断时效性意图的强弱,无需知道近期是否有大新闻
- 按需求强度分为4档:强、中、弱、无
- 识别方法:BERT等语义模型
(3)周期时效性:在每年特定时间表现为突发时效性,在其他时间表现为无时效性
- 例:双十一、春晚小品、高考作文、奥斯卡
- 可以不做任何处理。当查询词表现出突发时效性时,会被算法挖掘到
- 可以通过人工标注、数据挖掘识别周期时效性查询词
个性化
反映在预估点击率、交互率上,搜索结果千人千面
考虑到不同用户有不同偏好,搜索引擎可以根据用户特征做排序(类似推荐系统)
- 用预估点击率、交互率来衡量用户对文档的偏好
- 结合相关性、内容质量、时效性、个性化(即预估的点击率和交互率)等因子对候选文档排序
为什么需要个性化和点击率模型?
- 查询词越宽泛(例如“头像”),就越需要个性化排序
- 宽泛的查询词(例如“头像”)相关的文档数量巨大,其中小部分是用户感兴趣的
- 精准的查询词(例如“权力的游戏龙妈头像”)不需要个性化
- 预估点击率和交互率有利于提升相关性和内容质量
- 相关且高质量的文档更容易被点击、点赞、收藏、转发
- 与BERT等语义模型互补,解决bad case
- 即便是非个性化排序,也会用模型预估点击率和交互率(从另一个角度反映出相关性和内容质量),有助于提升排序效果
3、搜索引擎的评价指标
北极星指标(也叫核心指标):
- 用户规模、留存率(用户更多更活跃)
- 单个策略不容易提升规模和留存
- 对于某些垂类搜索引擎,如电商搜索,还有商品交易总额等
中间指标(与北极星指标正相关):
- 用户的点击等行为,反映搜索质量的好坏
- 做AB测试,中间指标很容易显著
人工体验评估:
- 人工评估搜索体验,让标注员评估搜索结果好坏
- 考察GSB、DCG等指标
北极星指标:用户规模&留存
(1)用户规模:日活用户数(Daily Active User,DAU),或月活用户数(Monthly~,MAU)
- 搜索日活(Search DAU)、推荐日活(Feed DAU)
- 搜索渗透率 = Search DAU / APP总体的DAU。搜索体验越好,用户越喜欢用搜索功能,搜索渗透率越高(百度应该看推荐渗透率,因为它们主要功能就是搜索)
提升搜索日活、搜索渗透率的方法:
- 搜索的体验优化,可以提升搜索留存,从而提升搜索日活
- 产品设计的改动,从推荐等渠道向搜索导流,推荐的用户更频繁地用搜索,提升搜索渗透率,从而提升搜索日活
(2)用户留存:APP的次7日内留存(次7留)
- 2月1日有1亿用户使用APP
- 这1亿人中,有8千万在2月2~8日使用APP至少一次
- 2月1日的次7留 = 8千万 / 1亿 = 80%
常用的留存指标:次1留、次7留、次30留(次n留随n单调递增:次1留 ≤ 次7留 ≤ 次30留)
把APP多个功能单独拆出看留存指标:APP总体次n留、搜索次n留、推荐次n留
现在更流行LT7和LT30留存指标(什么是LT?),原因:LT是加和,次N留是OR,加和波动更小,更容易显著
中间指标:用户的点击等行为
规模和留存指标未必适合评价单个策略
- 单个策略很难显著提升规模和留存(很难达到统计显著性)
- 即便能达到,规模和留存指标也需要很长时间才能显著(不利于快速迭代模型和策略)
规模和留存指标更适合作为大盘长期指标观察
- 评估整个团队长期的表现(所有策略叠加)
- 长期优化搜索体验,规模和留存会稳定提升,反映在AB测试的holdout上
中间指标:与规模和留存强关联,且容易在AB测试中显著
(1)点击率&有点比:
- 文档点击率:
- 搜索结果页上文档被用户看到,算作曝光
- 文档点击率 = 总点击数 / 总曝光数
- 文档点击率很低,通常是10%
- 有点比(查询词点击率):
- 搜索结果页上,用户点击任意一篇文档,则本次搜索算有点击(是否找到至少一篇用户需要的文档)
- 有点比 = 有点击的搜索次数 / 总搜索次数
- 有点比通常是70%
- 首屏有点比:
- 仅当点击发生在首屏,本次搜索算有点击(考察排序的效果,是否把用户需要的文档排在首屏)
- 首屏有点比 ≤ 有点比
改进排序策略通常会同时提升以上三种指标,改进召回策略可以提升文档点击率和有点比(因为首屏的几篇文档主要由排序决定)
(2)首点位置:用户需要的文档排名是否靠前
- 平均首点位置:
- 一次搜索之后,记录第一次点击发生的位置
- 如果没有点击,或者首点位置大于阈值x,则首点位置取x
- 对所有搜索的首点位置取平均
- 平均首点位置小,说明符合用户需求的文档排名靠前,用户体验好
- 优化搜索排序,通常会同时改善有点比、首屏有点比、平均首点位置,三者与留存指标强相关
(3)主动换词率:没搜到用户需要的文档,用户会换词重搜
- 如果用户搜到需要的文档,通常不会换查询词
- 例1:女性用户搜 “机械键盘”,结果大多是黑色的,不符合用户喜好,个性化差,用户会换词为 “机械键盘 女性”
- 例2:搜 “权利的游戏”,搜索引擎没能自动纠错,搜到的文档很少、质量不好,用户会换词为 “权力的游戏”
- 一定时间间隔内,搜的两个查询词相似(比如编辑距离小),则被认定为换词
编辑距离 - 力扣(LeetCode)
主动换词 vs 被动换词:
- 主动换词:原因是没找到满意的结果,说明搜索结果不好
- 被动换词(说明搜索引擎很智能):比如搜索建议“您是不是想搜权力的游戏”,用户点击建议
(4)交互指标:文档是用户非常需要的,那么用户会点赞、收藏、转发、关注...
- 用户点击文档进入详情页,可能会点赞、收藏、转发、关注、评论
- 交互通常表明用户对文档非常感兴趣(强度大于点击),因此可以作为中间指标(类似于有点比、首点位置、换词率)
- 交互行为稀疏(每百次点击,只有10次点赞、2次收藏),单个交互率波动很大,且在AB测试中不容易显著
- 取各种交互率的加权和作为总体交互指标,权重取决于交互率与留存的关联强弱
中间目标 -> 留存目标:
- 体验优化的策略往往同时改善多种中间指标:有点比、首屏有点比、平均首点位置、主动换词率、交互指标(短期内AB就会显著)
- 单个体验优化的策略很难在短期内显著提升留存指标(通常微弱上涨,不具有统计显著性)
- 只要中间指标普遍正向,实验就可以推全
- 上述中间指标与留存有很强的关联,长期持续改善中间指标,留存指标会稳定上涨
人工体验评估
(1)Side by Side评估:判断新旧两种策略谁的结果更好,评价指标是GSB(Good Same Bad)
随机抽一批搜索日志,取其中查询词、用户画像、场景。运行新旧两种策略,得到两个搜索结果页(文档列表,标注员可以看到标题、摘要、首图等信息)
- 固定查询词、用户、场景(时间、地点、手机型号等),搜索结果的差异只来自于策略
- 随机抽样搜索日志时,非均匀抽样(否则高频查询词太多),需要覆盖高频、中频、低频查询词
对于一条查询词,人工评估两个列表,分别对应新旧两种策略
- 基于查询词、用户画像、搜索场景,判断左右两个列表谁更好
- 盲评,即新策略出现在左、右的概率都是50%
- 不是判断具体哪篇文档更好,而是判断哪个列表整体更好
使用GSB作为评价指标:
- 如果新策略更优,记作Good(G)
- 如果两者持平,记作Same(S)
- 如果旧策略更优,记作Bad(B)
- 例:评300条查询词,GSB为50:220:30,G>B,新策略更好
决定一个实验是否可以推全,该用有点比这样的中间指标,还是Side by Side人工评估?后者争议比较大,存在很多缺点:
- 评估过于主观,评估标准未必与普通用户体验一致
- 每次仅评价几百个搜索结果页,结果噪声大,稳定性不如AB测试(AB测试虽然单次结果很随机,但样本量大,统计意义上可靠)
- 速度慢于AB测试,影响开发迭代效率
- 人工成本比较贵
- 不适合强个性化搜索引擎,个性化较难处理,仅凭用户画像难以判断用户真实需求
(2)月度评估:评价指标为平均DCG(Discounted Cumulative Gain),与自己往期、竞对作对比,判断搜索团队整体水平
每个月随机抽取一批搜索日志(用户实际看到的搜索结果),每条搜索日志包含查询词q、用户u、场景c、排名前k的文档d1~dk
- 随机抽样搜索日志时,非均匀抽样,比例固定,需要覆盖高频、中频、低频查询词
- 文档数量k取决于平均下滑深度(用户平均浏览结果页的前k篇文档),比如k=20
标注员评估每一篇文档,打分 score(q, u, c, di),越大说明文档di越好
- 可以单独给相关性、内容质量、时效性打分
- 也可以只打一个综合满意度分数(有具体的分档方法)
用DCG评价一次搜索 (q, u, c, d1, ..., dk) 结果的好坏,搜索结果页整体越好,DCG就越大:
- 评价的不是单独文档,而是搜索结果页整体好坏
- 分母:文档排名越靠后,这篇文档对用户体验的影响越小,权重越低
- 一个DCG分数是对一个搜索结果页整体的评价
对所有搜索日志,取DCG的均值,作为月度评估的结果
- 可以是自我对比,是否优于往期的DCG
- 可以与竞对对比,是否优于竞对的DCG
(3)两者区别:
- 目的不同:前者决策新策略是否推全,后者判断搜索团队整体水平,而不是看单个策略
- 指标不同:前者的指标是GSB,后者的指标是DCG
- 有无争议:前者充满争议,后者没有缺点和争议
DAU增长是好事,但人均搜索次数增长不一定是好事,不代表用户体验变好
4、搜索引擎的链路:查询词处理、召回、排序
查询词处理:分词、词权重、类目识别、意图识别、查询词改写等多个功能模块,后面召回和排序会使用查询词处理的结果
召回:从海量文档中找出几万篇与查询词相关的文档,二三十条召回通道同时运行,各自有一些配额。召回结束后,会用规则或简单模型做个初步筛选,把文档数量降低到几千,再送去排序服务器
排序:决定搜索结果页上文档展示的顺序。需要计算相关性、点击率、内容质量、时效性等很多分数,然后用规则或模型融合这些分数,给出最终的排序
- 推荐系统排序主要靠预估点击率和交互率,搜索引擎排序中的预估点击率和交互率是个性化分数,此外还需要相关性、时效性、内容质量等分数综合,其中相关性最重要
查询词处理
只要有分词就能做文本召回,如果用向量召回甚至连分词都不需要;除分词之外的其他功能(词权重、类目识别、意图识别、改写等)都是为了用搜索引擎效果更好,而非必不可少
查询词处理有个缓存,如果查询词命中缓存,就直接读取缓存中的查询词处理结果,不需要调用各个服务做计算。对于通用搜索引擎,几百万个高频查询词就能覆盖每天大部分的搜索请求
分词(Tokenization)
中文搜索引擎必不可少,主要给文本召回使用(文本召回必须要把查询词切成多个较短的term)
- 例:冬季卫衣推荐 —> 冬季/卫衣/推荐
为什么需要做分词?
- 文本召回根据词(term)在倒排索引中检索文档
- 倒排索引的key大多是“冬季”、“卫衣”、“推荐”这样的常用词,数量不大
- 假如倒排索引的key是“冬季卫衣推荐”这样的词,倒排索引会过于巨大
词权重(目的是丢词)
主要是给召回使用
- 例:冬季卫衣推荐 —> 冬季/卫衣/推荐,词权重为 卫衣(绝对不能丢弃)>冬季(若丢弃对搜索结果有较大影响)>推荐(若丢弃,查询词语义基本不变,没有影响)
为什么要计算词权重(Term Weight)?
- 如果查询词太长,没有文档可以同时包含其中所有词,文本召回找不到用户想要的文档,需要丢弃不重要的词(告诉文本召回哪些term不重要,可以丢弃)
- 召回结束之后需要用简单的规则或模型计算相关性,对文档做个初步筛选。计算查询词与文档的相关性时,可以用词权重做加权
类目识别
每个平台都有各自的多级类目体系
- 一级类目:美妆
- 二级类目:彩妆、护肤、美甲、香水、医美
用NLP技术识别文档、查询词的类目(多标签分类问题)
- 在文档发布(或被爬虫获取到)时,离线识别文档类目
- 在用户做搜索时,在线识别查询词类目
- 一篇文档或者一个查询词可以同时属于多个类目
召回模型、排序模型将文档、查询词类目作为特征
查询词意图识别
一条查询词可以同时带有多种意图
- 时效性意图:查询词对文档“新”的需求,召回和排序均需要考虑文档的年龄
- 例:新款电动车测评:一般时效性意图;热点新闻:突发时效性意图
- 地域性意图:召回和排序不止需要文本相关性,还需要结合用户定位地点、查询词提及地点、文档定位地点
- 用户名意图:用户想要找平台中的某位用户,应当检索用户名库,而非检索文档库
- 求购意图:用户可能想要买商品,同时在文档库、商品库中检索
查询词改写
技术难度最大。定义:用户输入查询词q,算法将其改写成多个查询词 q'1 ~ q'k(独立用 q、q'1 ~ q'k 做召回,对召回的文档取并集)
查询词改写有什么用?
- 解决语义匹配、但文本不匹配的问题(文本召回只能做字面上的匹配,如:LV = LOUIS VUITTON = 路易威登,语义相关,但使用文本召回无法检索)
- 解决召回文档数量过少的问题(q不规范表达,或q过长,导致召回结果很少。如:老谋子拍的电影 = 张艺谋的电影;身高160体重120年龄20女穿搭 = 微胖女大学生穿搭)
召回(Information Retrieval)
给定查询词q,从文档库(数亿篇文档)中快速检索数万篇可能与q相关的文档{d}
- 文本召回(即文本匹配,最传统的方法):借助倒排索引,匹配q中的词和d中的词
- 向量召回(双塔召回):用BERT这样的深度学习技术,将q和d分别表征为向量xq和zd。给定查询词向量xq,在向量数据库中做ANN查找,召回相似度高的文档zd
- KV召回(离线构造的KV索引,用于高频查询词的召回):对于高频查询q,离线建立 q -> List<d> 这样的 key-value索引。线上直接读取索引,获取q相关的文档
文本召回(借助倒排索引)
离线处理文档,建立倒排索引(给定词t,可以快速找到所有包含t的文档):
- 给定查询词q,做分词得到多个词t1~tk
- 对于每个词ti,检索倒排索引,得到文档的集合Di
- 求k个集合的交集D1∩...∩Dk,作为文本召回的结果
- 交集可能很小甚至为空,因此需要对q做丢词、改写
向量召回(双塔模型)
- 借助深度学习技术,把查询词和文档表征为向量,计算两个向量的内积或余弦相似度
- 训练模型时,用相关性或者点击作为预测目标
- 在线上通过向量最近邻查找,检索与查询词相关的文档
KV召回(作为补充)
- key:用户真实搜过的查询词,在过去一段时间被搜的次数高于某个阈值
- value:文档列表,每个查询词都对应很多篇文档,由于离线做过筛选,这些文档与查询词都有高相关性
排序(Ranking)
排序的依据,也即影响用户满意度的因素:
- 相关性(主要决定因素):查询词和文档之间的关系,重要性最高,在线上用BERT模型(4/6/12层都有,取决于算力)实时计算查询词和文档的相关性
- 内容质量:指文档的文本和图片质量、以及作者或者网站的EAT。算法离线分析文档的内容质量(在文档发布或被爬虫检索到时,算法就会计算文档的内容质量,得到很多分数),把多个分数写到文档画像中
- 时效性:主要指查询词对“新”的需求。查询词处理分析时效性,把结果传递给排序服务器,如果查询词有时效性需求,那么文档年龄会成为排序的主要因素之一
- 个性化:在不同的搜索引擎中,个性化的重要性各不相同。在线上用多目标模型预估点击率和交互率(与推荐系统几乎相同)
问题:某搜索引擎的时效性很差,查询词处理、召回、排序分别能做什么?
- 查询词处理时,识别时效性意图,比如“今天”、“最近”这类词有显性时效意图,“股票”、“天气”这类则有隐性时效意图
- 召回阶段,如果query有时效性意图,需要触发特殊的召回通道,新文档召回通道的quota不固定,会跟查询词意图挂钩
- 排序阶段时效性只在最终融合的时候用
相关性
最重要,比内容质量、时效性、个性化重要
1、定义与分档
工业界做相关性的标准流程:制定标注规则 -> 标注数据 -> 训练模型 -> 线上推理
- 搜索产品和搜索算法团队定义相关性标注规则
- 人为将 (q,d) 的相关性划分为4个或5个(如百度)档位。后以4个为例
- 相关性分档规则非常重要,假如日后有大幅变动,需要重新标注数据,丢弃积累的数据
- 产品和算法团队监督指导标注团队的工作,累积数十万、数百万条 (q,d) 样本
- 算法团队用人工标注的数据训练相关性模型
相关vs不相关
(1)字面匹配vs需求匹配:相关性不是字面上的匹配,而是需求匹配
- 相关性是指 d能满足q的需求或回答q提出的问题(d是文档,q是查询词)
- 哪怕q和d字面上完全不匹配,两者也可以被判定为相关
- 即便q和d字面匹配,两者也可能不相关
(2)相关性标注只考虑相关性,不考虑内容质量、时效性等因素
- 满足相关性,但内容质量低,OK
- 满足相关性,但时效性低,OK
(3)多意图查询词:查询词q可能有多种意图,文档d只需命中一种意图就算相关
- 越短的查询词就越可能有多意图
- 若没有命中用户的真实意图,是个性化的问题,搜索引擎没有根据用户画像做好查询词理解和排序
(4)上位词、下位词
- 搜上位词,出下位词,判定为相关(因为下位词∈上位词)
- 搜下位词,出上位词,通常判定为不相关
(5)丢词的判定:丢词即文档不能完全满足查询词的需求,丢失了一部分需求。具体要看d能否满足q的主要需求或回答q提出的问题
- 丢弃核心词,判定为不相关
- 丢失重要限定词(主观性较强),判定为不相关
- 丢失不重要限定词,判定为相关
档位细分
(1)根据内容占比划分高、中档位
- 如果 (q,d) 相关,则进一步划分为高(超过50%)、中(不超过50%)两档
- 细分规则:满足需求的内容的篇幅占比是否超过50%
(2)根据参考价值划分低、无档位
- 如果 (q,d) 不相关,则进一步划分为低(有参考价值)、无(无参考价值)两档
- 细分规则:文档是否具有参考价值(用户可能愿意看这篇文档,代表有参考价值)
总结
标注流程
由算法团队抽取待标注样本
- 从搜索日志中随机抽取n条查询词,n的大小取决于标注人力。既有高频查询词,也有中、低频查询词(假如中低频查询词占比太小,训练出的模型在中低频查询词上的表现会比较差)
- 给定q,从搜索结果中抽取k篇文档,组成二元组 (q, d1) ~ (q, dk),4个相关性档位的样本数量尽可能平衡
- 不能直接取搜索结果页排名topk的文档,否则高档位(即高相关)文档过多,低档位文档过少。样本有偏不利于训练
由产品团队和算法团队监督标注过程和验收结果
- 遇到难以界定档位的 (q, d),由产品和算法团队做界定和解释
- 一条样本由至少两人标注,两人标注的结果需要有一致性。如果标注不一致,样本会被直接丢掉,或找第三人标注
- 一致率指两个人的标注结果有多大比例是相同的。一致率大于某个阈值,如80%,才会被接受
- 若一致率合格,再由产品团队抽查标注结果(可以认为产品团队的标注结果是正确的,为ground truth),要求准确率高于某个阈值
- 只靠抽查还是不够(数量太少),可以事先往数据中埋雷(如往1w条待标注样本中掺杂200条产品团队自己标注的样本),考察埋雷样本的标注准确率
2、评价指标(AUC、正逆序比、DCG)
用AUC和PNR作为离线评价指标(看相关性模型在测试集上的表现够不够好)
- pointwise评价指标:AUC(Area Under the Curve)
- pairwise评价指标:PNR(正逆序比,Positive to Negative Ratio)
用DCG评价模型在线上排序的效果(线上直接搜索结果页存在搜索日志里,事后做抽样,让人工标注相关性,然后计算DCG,评价排序是否合理)
- listwise评价指标:DCG(Discounted Cumulative Gain)
pointwise:AUC (离线)
把相关性看作二分类问题,独立对待每一对 (q, d)二元组。训练集还是4个小档位(高中低无),但测试集只用2个大档位(把测试集相关性档位转化为0/1)
- 高、中两档合并,作为标签y=1
- 低、无两档合并,作为标签y=0
相关性模型输出预测值p∈[0,1],p的值越大,表示模型认为查询词和文档越有可能相关
二分类评价指标:准确率、召回率、F1、AUC(工业界最常用AUC来评价搜索相关性)
- 调整二分类的阈值,获得很多组假阳性率&真阳性率的二元组,获得ROC曲线
- 用AUC评价模型的预测是否准确。比较好的相关性模型的AUC在 0.8 ~ 0.95 之间
pairwise:PNR (离线)
每次取两个二元组做对比。问题:只考虑文档两两之间的序,不考虑整体的序
- <高,高>这样的pair,可以看成正序对,也可以忽略掉这样的二元组
以下两种情况正逆序比相同,都是13:2,在pairwise评价指标下是等价的。但实际上,右边的情况要优于左边(因为错误发生在后面,用户浏览搜索结果页时通常是从上到下浏览,要保证前面的结果都是高相关性):
listwise:DCG (线上)
更看重排在前面的文档,给更大的权重
(1)pairwise指标 vs listwise指标
- 有n篇候选文档,根据模型打分做降序排列,把文档记作d1, ..., dn(此时不知道真实相关性分数)
- d1, ..., dn的真实相关性分数为y1, ..., yn(人工标注相关性档位,档位映射到[0,1]区间上的实数)
- 理想的排序为 y1 ≥ y2 ≥ ... ≥ yn,即模型打分的序与真实相关性分数的序一致,此时pairwise和listwise指标都最大化
- 逆序对会导致pairwise和listwise指标减小。逆序对出现的位置不影响pairwise指标;而逆序对越靠前,对listwise指标造成的损失越大
(2)CG(Cumulative Gain)
- 真实相关性分数y1~yn不一定是降序排列的
- k是人工设置的参数,一般为二三十
- CG@k可以评价排序做的准不准,即模型有能力从n篇文档中选出k篇最相关的时,CG@k最大
(3)DCG(Discounted Cumulative Gain)
【相关性评价指标】总结:
相关性有pointwise、pairwise、listwise评价指标
- pointwise:单独评价每一个 (q,d)二元组,判断预测的相关性分数与真实标签的相似度。不考虑二元组之间的关系;
- pairwise:对比 (q,d1)和(q,d2),判断两者的序是否正确(正序对或逆序对)
- listwise:对比 (q,d1)~(q,dn),判断整体的序关系的正确程度
离线评价指标 (point&pair-wise)
事先准备人工标注的数据,划分为训练集和测试集
完成训练之后,计算测试集上的AUC和PNR(分别是pointwise和pairwise评价指标)
相关性有4个档位,为什么用AUC(AUC是评价二分类的指标),而不用多分类的评价指标(Macro F1和Micro F1)?
- 简而言之,相关性虽然有4个档位,但不是多分类问题
- 相关性的标签存在序关系:高>中>低>无
- 多分类把4种标签看作4个类别,忽略其中的序关系
- 把高错判为中,或错判为无,错误严重程度不同,但被多分类视为同等的分类错误
线上评价指标 (listwise)
一个搜索session是用户实际做过的一次搜索,保存在搜索日志中,包含:用户搜索q,搜索结果页上按顺序展示文档d1~dn
- 从搜索日志中抽取一批session,覆盖高、中、低频查询词
- 对于每个session,取排序最高的k篇文档d1~dk
- k的设定取决于用户浏览深度,比如k=20
- 高频查询词前20篇文档几乎都是高相关,指标过高
- 高频查询词的k设置的较大(比如k=40),低频查询词的k设置的较小(比如k=20)
- 人工标注相关性分数,记作y1~yk
想要对线上实际结果做评估,没办法事先准备一个测试集,只能在做评估的时候标注,每做一次评估就要标一批数据,通常一个月做一次,故叫月度评估,评价指标为DCG
思考题:NDCG
NDCG是归一化的DCG(N表示Normalized)
问题:NDCG可否代替DCG用作线上评价指标?NDCG有什么缺陷?
- 先做召回,再做排序,假设召回的结果全是低相关文档
- DCG低,但NDCG不一定低,故DCG更合理
3、文本匹配(TF-IDF、BM25、词距)
在深度学习成熟之前,搜索引擎主要靠文本匹配来判断相关性
- 传统的搜索引擎使用几十种人工设计的文本匹配分数,作为线性模型或树模型的特征,模型预测相关性分数
- 词匹配分数(TF-IDF、BM25)、词距分数(OkaTP、BM25TP)、其他分数(类目匹配、核心词匹配)
- 2020年后,搜索排序普遍放弃文本匹配,改用BERT模型,仅剩文本召回使用文本匹配做海选
链路上的相关性模型
召回海选:
- 打分量:数万
- 模型:文本匹配分数+线性模型,或双塔BERT模型
粗排:
- 打分量:数千
- 模型:双塔BERT模型,或单塔BERT模型(又叫交叉BERT模型)
精排:
- 打分量:数百
- 模型:单塔BERT模型(4/6/12层)
词匹配分数 (反映查询词和文档的相关性)
中文分词:将查询词、文档切成多个字符串
- 查询词:q = "好莱坞电影推荐"
- 分词得到:Q = {好莱坞, 电影, 推荐}
Q中的词在文档d中出现次数越多,则q与d越可能相关。TF-IDF和BM25都是基于上述想法
TF-IDF
(1)TF(词频,Term Frequency)
分词结果记作集合Q,t∈Q是一个词(term),词t在文档d中出现次数叫做词频,记作
- 越大,说明t与d越可能相关
- 越大,则q与d越可能相关
除以文档长度,即归一化的词频
语义重要性在查询词处理环节计算,需要用深度学习计算。在深度学习成熟之前,词匹配算不了term weight,有一个简单的方法给词设定权重:一个term在越多文档中出现,它的判别能力就越弱,给它设定的权重就越低
(2)IDF(Inverse Document Frequency)
对于人工智能论文数据集,“深度学习”的IDF很小;对于维基百科数据集,“深度学习”的IDF很大
(3)TF-IDF(Term Frequency-Inverse Document Frequency)
有很多种不同的定义
BM25 (TF-IDF的变体)
在所有词匹配分数中,BM25(Okapi Best Match 25)是最强的。如果学一个线性模型或者树模型预测相关性,BM25的特征权重是最高的
词袋模型 (bag of words)
TF-IDF和BM25都属于词袋模型,隐含了词袋模型假设:只考虑词频,不考虑词的顺序和上下文
- 例1:男朋友 / 送 / 的 / 礼物 vs 送 / 男朋友 / 的 / 礼物
- 例2:白 / 衬衫 / 灰 / 裤子 vs 灰 / 衬衫 / 白 / 裤子
缺点:忽略词序和上下文,丢失了语义,导致计算出的相关性分数不准确。所以传统相关性模型远不如BERT这样的语义模型
前深度学习时代有很多词袋模型,例如LSA、LDA等都可以将查询词和文档映射为向量
- LSA:Latent Semantic Analysis
- LDA:Latent Dirichlet Allocation
RNN、BERT、GPT都不是词袋模型,会考虑词的顺序和上下文,更好地理解查询词和文档的语义
词距分数 (Term Proximity,从另一个角度反映相关性)
如果用TF-IDF或BM25计算相关性,会得出错误结论。想要避免这类错误,需要用到词距(Q中的两个词出现在文档d中,两者间隔多少词。词距越小,Q与d越可能相关)
有很多种词距分数,这里只介绍OkaTP
OkaTP (既考虑了词频,也考虑了词距)
- 第一项跟BM25的区别是,把Term Frequency 换成了词距分数TP 。TP越大,该项就越大
- 第二项,两个term各有一个IDF,取两者中较小的那一项
- 对两个term的组合求加和
【文本匹配】总结
词匹配分数包括TF-IDF、BM25等
- TF:词在文档中出现次数越多越好
- IDF:词在较少的文档中出现,则给词较高的权重
- 基于词袋模型,只考虑词频,不考虑词序和上下文
词距分数包括OkaTP等
- 查询词Q中的词在文档中出现次数越多越好
- 查询词Q中的任意两个词在文档中越近越好
传统搜索相关性会用很多人工设计的文本匹配分数,如词匹配分数、词距分数等一共十几种分数,把它们作为特征,用线性模型或树模型预测相关性。
基于文本匹配的传统方法没有真正理解查询词和文档的语义,效果远不如深度学习。现在只有召回海选还用这种方法,用较小代价排序海量文档。
4、BERT模型结构及线上推理
现代搜索引擎普遍使用BERT模型计算查询词q和文档d的相关性,文本匹配的方法正在逐步被淘汰
交叉/单塔BERT模型:把查询词和文档拼成一个序列输入BERT,准确性好,但推理计算量大,通常用于搜索链路的下游(精排、粗排)
- 交叉:自注意力层对查询词和文档做了交叉
双塔BERT模型:不够准确,但是推理代价小,给上万篇文档打分也没有问题,通常用在链路上游(粗排、召回海选)
- 粗排给几千篇文档打分,可能用交叉BERT(此时模型应较小,只有2层或4层),也可能用双塔BERT
- 召回海选给几千或者几万篇文档打分
训练相关性BERT模型的4个步骤:预训练、后预训练、微调、蒸馏
交叉BERT模型 (准确性好,但推理代价大)
输入的查询词、标题、正文(有可能会包含更多字段,如摘要、Anchor Query)会被切分为token,每个token可以是汉字、词、拉丁字母、英文单词或其他字符串。token会被Embedding层表征为向量
【Anchor Query】
给定文档d,生成相关的查询词q1~qk
- 构造一个(q,d)数据集,q与d相关性高
- 训练一个生成模型,如Transformer,输入d,生成q
- 做后处理,用相关性模型排除与d相关性不够高的q
与d高相关的查询词{q}叫做Anchor Query,作为文档内容输入相关性BERT模型
可以将Anchor Query看作文档的关键词或极简的摘要,起到“打标签”的作用。如果Anchor Query质量高,可以让BERT更准确预测相关性
- 对交叉BERT模型的提升有限,对双塔BERT模型提升较大
- token embedding
- position embedding:token出现在第几个位置上
- segment embedding:不是必须的,不用的话模型也能根据位置编码和[SEP]分隔符区分查询词、标题、正文3个字段
模型的输入有n个token,被表征为n个向量;然后经过很多自注意力层和全连接层,最终模型输出一个0~1之间的实数作为相关性分数
分词粒度:字粒度 vs 字词混合粒度
需要把查询词和文档切分成很多token,具体的分词方法对相关性有很大影响。对于中文,有2种分词粒度:
- 字粒度:将每个汉字/字符作为一个token
- 词表较小(几千),只包含汉字、字母、常用字符。词表较小则Embedding Table也较小
- 优点:实现简单,无需做分词
- 第一个版本的相关性BERT最好用字粒度,实现简单,效果也还行,可以作为好的baseline
- 字词混合粒度:做分词,将分词结果作为tokens
- 词表较大(几万、十几万),包含汉字、字母、常用符号、常用中文词语、常用英文单词
- 与字粒度相比,字词混合粒度得到的序列长度更短(即token数量更少,可以少一半左右)
- 参考WoBERT,GitHub - ZhuiyiTechnology/WoBERT: 以词为基本单位的中文BERT
- 字词混合粒度更复杂,效果更好
序列更短(token数量更少)有什么好处?
- BERT推理的计算量是序列长度/token数量的超线性函数,介于线性和平方时间复杂度之间。自注意力层是平方时间复杂度,全连接层是线性时间复杂度。序列越长,推理代价越大
- 为了控制推理成本,会限定token数量,例如128或256
- 如果文档超出token数量上限,会被截断,或者做抽取式摘要
- 使用字词混合粒度,token数量更少,推理成本降低(字词混合粒度的序列长度可以比字粒度少一半左右,如字粒度需要256 token,字词混合粒度只需要128 token)
推理降本
精排有几百个(q,d)二元组,粗排有几千个,由于交叉BERT模型推理代价很大,对每个(q,d)二元组计算相关性分数score,代价很大。有几种降低推理成本的方法:
(1)用内存换计算,用Redis这样的KV数据库缓存 <q, d, score>
- 把查询词和文档id作为key,相关性分数作为value
- 线上做排序时要计算相关性,如果(q,d)命中缓存,则避免计算。用户的搜索大多集中在很少的高频查询词上,由于(q,d)重复率很高,这种缓存机制可以避免一半以上的计算
- 如果超出内存上限(通常几个TB的内存),按照LRU(Least Recently Used,最近最少使用)清理缓存
(2)模型量化技术,例如将float32转化成int8
神经网络的参数都是用浮点数表示的,通常为float32,也叫单精度浮点数,占 32bits 的存储。把float32压缩成int8这样的低精度整数
- 训练后量化(PTQ,post-training quantization):训练不变,量化和训练互不影响,训练完了再做量化,把float32压缩成int8
- 训练中量化(QAT,quantization-aware training):训练和量化是结合在一起做的,训练模型时要做前向传播和反向传播,前向传播使用量化后的低精度整数做计算,反向传播仍使用原始的浮点数权重和浮点数梯度
(3)文本摘要技术,使用文本摘要降低token数量
- 如果文档长度超出上限,则用摘要替换文档,优于直接截断文档
- 在文档发布时计算摘要。可以是抽取式(取一些关键的句子和段落作为摘要),也可以是生成式(用大语言模型生成摘要)
- 如果摘要效果好,可以将token数量上限降低,比如从128降低到96
双塔BERT模型 (准确性不好,但推理代价小)
双塔BERT模型既可以用于召回,也可以用于排序。这里只讲如何用于排序
左右的神经网络分别把查询词和文档映射成向量
- 左边的神经网络(查询词塔)在线上实时做推理,用户做一次搜索,只有一个查询词,左塔做一次推理,代价很小
- 查询词类目等特征由查询词处理环节提供
- 右边的神经网络(文档塔)不会在线上做推理,而是在文档发布时离线做一次推理,把算出的文档向量表征存入哈希表(key是文档id,value是向量表征),线上计算相关性时就不用再计算文档的向量表征了
双塔的输出向量计算内积,再过个sigmoid变换,就得到查询词和文档的相关性分数
【BERT模型结构及线上推理】总结
交叉/单塔BERT模型:
- 准确性高,计算量大,适用于精排、粗排
- 字词混合粒度分词降低序列长度,即token数量
- 用KV内存数据库缓存 <q, d, score>,可以避免大部分计算
- 用模型量化技术,把float32转化成int8,降低推理成本
- 设置较小的token数量上限,将长文档替换成摘要
双塔BERT模型:
- 准确性低,计算量小,适用于粗排、召回海选
- 事先离线计算每篇文档d的向量表征zd,将 (d, zd) 存入哈希表
- 线上计算 (q,d) 的相关性时,给定候选文档d,从哈希表中读取它的向量表征zd
- 线上计算查询词q的向量表征xq,然后计算内积 <xq, zd>,作为(q,d)相关性分数
5、BERT模型的离线训练
不论是交叉BERT还是双塔BERT,如果用在排序中计算相关性,两者的训练方法相同
训练相关性BERT模型
训练分4个步骤:预训练(pretrain)、后预训练(post pretrain)、微调(fine tuning)、蒸馏(distillation)
- 预训练:用MLM(Mask Language Model)等任务预训练模型。直接用开源的模型效果不差,但最好自己用搜索引擎的文档库做预训练,效果会更好
- 预训练量越大越好,跟后预训练数量相当
- 不用NSP,NSP是有害的
- 后预训练(新技术):利用用户的点击、交互数据训练模型,因为相关性越好的文档越有可能被点击和交互
- 后预训练的输入就是【q, d】,用两种label:y、MLM
- 微调:用人工标注的相关性数据训练模型
- 在相关性标注那节中讲到相关性可以分4档,但微调时使用的人工标注y应该是一个0到1的分数,两者之间的映射是自己定的,没有特别好的方法
- 蒸馏:得到更小的模型,加速线上的推理。先训练大模型再蒸馏小模型,效果远好于直接训练小模型
- 蒸馏阶段只需要teacher和student模型的label一样,不需要inputs一样
只讲后3个步骤
微调(fine tuning)
微调用监督学习训练模型,模型估计q和d的相关性
- 人工标注数十万、数百万条样本,每条样本为 (q,d,y),y为人工标注的相关性分数
可以把估计相关性看作回归任务,也可以看作排序任务
- 回归任务让预测的值p拟合y,起到“保值”的作用
- 给定(q,d),模型估计相关性为p
- p越接近真实标签y越好
- 排序任务让p的序拟合y的序,起到“保序”的作用。只在乎预测的序是否正确,不在乎预测的值离y是远是近
- 给定两条样本(q,d1,y1)和(q,d2,y2),相同的查询词q,满足y1>y2
- 模型预测的相关性分数p1和p2应当满足p1>p2,即正序对,p1<p2为逆序对
(1)回归任务
数据:(q1,d1,y1) ... (qn,dn,yn),其中yi是归一化后的相关性分数,yi∈[0,1];模型预测(qi,di)的相关性为pi
交叉熵损失函数效果会更好
- 用CE Loss时,标签y不止是0(最低相关性档位)和1(最高相关性档位),还可以是0~1之间的小数(其余相关性档位)
(2)排序任务
数据:一条样本包含一条查询词q和k篇文档d1~dk
对于(q,di),真实相关性分数记作yi,模型预测的相关性记作pi
- 两种排序方式:按照yi排序、按照pi排序
- 排序任务不在乎pi和yi的值是否接近,只在乎两种排序是否接近
设yi>yj,损失函数应当鼓励pi-pj尽量大
- 如果pi≥pj(模型预测正确),则称(i,j)为正序对
- 如果pi<pj(模型预测错误),则称(i,j)为逆序对
- 损失函数应当惩罚逆序对,鼓励正序对 —> 鼓励pi - pj尽量大
- pi - pj 越大,则损失函数越小。最小化损失函数,可以鼓励正序对,减少逆序对
- gamma 是一个>0的超参数,控制 logistic函数的形状
- 最小化加和,会鼓励模型给k篇文档的排序,接近按y做的排序
【微调】小结:
- 可以把估计相关性看作回归任务,也可以看作排序任务
- 看作回归任务,使用均方差损失(MSE)或交叉熵损失(CE),有利于提升AUC指标
- 看作排序任务,使用pairwise logistic损失,有利于提升正逆序比指标
- 不要把估计相关性看作多分类任务
- 相关性有多个档位,但档位之间是有序的,而不是无序的类别名称
- 如果同时用AUC和正逆序比作为离线评价指标,则同时使用CE和pairwise logistic损失
- 取两者的加权和作为优化的目标函数
后预训练(post pretrain)
1. Zou et al. Pre-trained language model based ranking in Baidu search. In KDD , 2021.2. Zou et al. Pre-trained language model-based retrieval and ranking for web search.ACM Transactions on the Web, 2022.
训练相关性模型:预训练 -> 后预训练 -> 微调 -> 蒸馏
后预训练的步骤:
- 从搜索日志中挑选十亿对(q,d)。对于48层BERT,数据量超过10亿的话,边际效益会越来越小,更多数据对指标的提升不大
- 自动生成标签:将用户行为x映射到相关性分数y_hat。自动生成的标签y_hat噪声很大,但仍然有很多信息量,这就是为什么后预训练有效
- 用自动生成的(q,d,y_hat)训练模型,方法与微调类似,都是监督学习。但额外加上预训练的MLM任务,避免预训练的结果被清洗掉
(1)步骤1:挑选(q,d)
搜索日志记录用户每次搜索的查询词q和搜索引擎返回的文档
根据搜索日志抽取查询词q,需要覆盖高、中、低频的q(不是均匀抽样,否则抽到的几乎都是高频查询词)
给定q,搜索日志记录搜到的文档d1~dn,以及模型估计的相关性分数(是精排相关性模型的打分,不是人工标注的。不需要很准确,只是用来筛选文档而已)
根据相关性分数,选取n篇文档的一个子集,均匀覆盖各相关性档位
(2)步骤2:自动生成相关性分数
步骤1根据搜索日志选出十亿对(q,d),对搜索日志做统计,得出(q,d)的点击率和多种交互率,记作向量x
- 得到十亿条样本(q,d,x),其中向量x是用户行为
- 根据点击和交互产生的向量x,其维度大小就是交互统计的特征数,比如关注点击率,点赞率,收藏率,转发率,那么这个x维度就是4,每个位置为对应值
相关性y与x存在某种函数关系,相关性越高,用户越有可能点击和交互。找出y与x的函数关系:y_hat = t(x)
- 选取几万对(q,d),人工标注相关性分数y
- 搜索日志记录了(q,d)的用户行为x
- 得到几万条样本(x,y),训练一个小模型t(x)拟合y。具体来说,定义一个小模型t(如GPT或小规模神经网络),它将用户行为x映射到相关性分数y,这样就可以自动生成标签y_hat,是对真实标签y的近似
小模型t 只能使用点击率、交互率等用户行为作为输入
- 尽量不使用文本特征作为输入
- 绝对不能用相关性BERT模型打分作为输入,否则会产生反馈回路(BERT模型打分 -> 训练小模型t -> 小模型t生成数据 -> 训练BERT模型)
对于所有十亿条样本(q,d,x),用训练好的小模型打分 y_hat = t(x),得到十亿条带自动生成标签的样本(q,d,y_hat),可以用它们来训练BERT模型
(3)步骤3:用生成的数据训练模型
前两步得到十亿条样本(q,d,y_hat),其中y_hat是自动生成的相关性分数。基于预训练的BERT模型,用(q,d,y_hat)做监督学习
监督学习同时用3个任务,取3个损失函数的加权和
- 回归任务,起到“保值”的作用(模型的输出尽量接近y_hat),有利于AUC指标
- 排序任务,起到“保序”的作用(鼓励正序对,惩罚逆序对),有利于正逆序比指标
- 预训练的MLM任务,避免清洗掉预训练的结果(后预训练的数据量很大,量级是十亿,会清洗掉预训练的结果)
后预训练为什么有效?
大幅增加了有标签样本数量(百万 -> 十亿)
- 人工标注的相关性数据只有几十万到几百万条(q,d,y)
- 后预训练使用十亿条(q,d,y_hat)
- 巨大的数据量使模型更准确
用户行为x与相关性y有很强的关联
- (q,d)的相关性越高,越有可能得到点击和交互
- 小模型可以根据点击率和交互率x较为准确地推断y
- 小模型生成的标签y_hat虽然有噪声,但也有很大的信息量
蒸馏(distillation)
为什么做蒸馏?
用户每搜一个查询词,排序需要用相关性BERT模型给数百、数千对(q,d)打分。BERT模型越大,计算量越大,给相关性的打分越准
为了平衡计算量和准确性,精排常用4~12层交叉BERT在线上做推理,粗排常用2~4层交叉BERT(或双塔BERT)
两种方法谁更好?
- 直接训练小模型(2~12层)
- 先训练48层大模型,再蒸馏小模型(better)
先训练48层BERT作为teacher,再蒸馏小模型,效果优于直接训练小模型。工业界经验:
- 48层对比12层,AUC高2%以上
- 48层蒸馏12层,参数量压缩了10倍以上,AUC几乎无损
- 48层蒸馏4层,AUC损失0.5%
怎样做蒸馏?
48层BERT大模型,参数量一二十亿
一些有效的蒸馏技巧
给student做预热,效果优于随机初始化,也优于只做预训练
逐层蒸馏代价大,多花算力,还不如增加蒸馏数据量
总结
预训练:拿与任务无关的文本训练,如预测被遮挡的词(MLM)
后预训练:结合回归、排序、预训练任务(MLM)
微调:数据量较小,一般几十万(最多几百万)条样本;监督学习,同时有回归和排序两种任务
蒸馏:用训练好的大模型给几亿条(q,d)打分,得到蒸馏数据;基于预热好的小模型,用蒸馏数据做监督学习;最终得到的小模型部署到线上做相关性
未完待续,坐等王老师更新~