三、知乎—搜索文本相关性与知识蒸馏
交互式BERT:用于精排
表示型BERT:用在召回、粗排,采用了 BERT 输出 token 序列向量的 average 作为句向量的表示
召回:语义召回模型整体是 BERT 相关性任务中双塔表示模型的一个应用。BERT 做为 encoder 来对 query 和 doc 进行向量的表示,基于 faiss 对全量 doc 向量构建语义索引,线上实时的用 query 向量进行召回。
下面详细介绍下知乎的语义召回模型。首先看个例子,对于「玛莎拉蒂 ghlib」这个 case,用户真正想搜的是「玛莎拉蒂 Ghibli」这款车,但用户一般很难记住完整的名称,可能会输错。在输错的情况下,基于传统的 term 匹配方式(Google 搜索的例子)只能召回“玛莎拉蒂”相关的 doc,而无法进行这辆车型的召回,这种场景下就需要进行语义召回。更通用的来说,语义召回可以理解为增加了字面不匹配但是语义相关的 doc 的召回。
知识蒸馏
对于BERT 的蒸馏我们做了大量的调研,并对目前主流的蒸馏方案做了归纳分类。基于任务维度来说,主要对应于现在的 pretrain + fine-tune 的两段式训练。在预训练阶段和下游任务阶段都有不少的方案涉及。技巧层面来分的话,主要包括不同的迁移知识和模型结构的设计两方面。后面我会选两个典型的模型简单介绍一下。
蒸馏的收益主要分为在线和离线两部分。
在线方面:
交互模型的层数从 12 层压缩到 6 层,排序相关性特征 P95 减少为原本的 1/2,整体搜索入口下降 40ms,模型部署所需的 GPU 机器数也减少了一半,降低了资源消耗。
表示模型语义索引存储规模 title 减为 1/4,content 维度从 768 维压缩至 64 维,虽然维度减少了 12 倍,但增加了倒排索引 doc 的数量,所以 content 最终减为 1/6,语义索引召回也有比较大的提升,title 减少为 1/3,content 减少为 1/2。精排模块需要线上实时查询离线计算好的向量,所以查询服务也有提升。
离线方面:
表示模型语义索引的构建时间减少为 1/4,底层知乎自研的 TableStore/TIDB 存储减为原来的 1/6,LTR 训练数据和训练时间都有很大的提升,粗排早期用的是 BM25 等基础特征,后来引入了 32 维的 BERT 向量,提升了精排精度。
四、美团—BERT搜索核心排序
用于核心搜索的“核心排序”中,蒸馏成2层交互BERT,预测的query-poi相关性分数作为排序的一个特征使用。
训练数据:
- 使用下单数据作为正样本,使用未点击过的数据构造负样
- Skip-Above采样:受限于App搜索场景的展示屏效,无法保证召回的POI一次性得到曝光。若直接将未被点击的POI作为负例,可能会将未曝光但相关的POI错误地采样为负例。为了保证训练数据的准确性,我们采用Skip-Above方法,剔除这些噪音负例,即从用户点击过的POI之上没有被点击过的POI中采样负例(假设用户是从上往下浏览的POI)。
引入品类信息:
- 对于模型输入部分,我们将Query、Doc标题、三级类目信息拼接,并用[SEP]分割,区分3种不同来源信息。对于段向量,原始的BERT只有两种片段编码EA和EB,在引入类目信息的文本信息后,引入额外的片段编码Ec。引入额外片段编码的作用是防止额外信息对Query和Doc标题产生交叉干扰。由于我们改变了BERT的输入和输出结构,无法直接基于MT-BERT进行相关性Fine-tuning任务。我们对MT-BERT的预训练方式做了相应改进,BERT预训练的目标之一是NSP(Next Sentence Prediction),在搜索场景中没有上下句的概念,在给定用户的搜索关键词和商户文本信息后,判断用户是否点击来取代NSP任务。
引入实体任务识别,多任务fine-tuning
Pairwise Fine-tuning
- 样本:单条样本为三元组<Query, Doc+, Doc->;
- loss:除了输入样本上的变化,为了考虑搜索场景下不同样本之间的偏序关系,我们参考RankNet[34]的方式对训练损失函数做了优化。
Partition-model,多业务问题
- Partition-model的思想是利用所有数据进行全场景联合训练,同时一定程度上保留每个场景特性,从而解决多业务场景的排序问题。
损失函数:选用优化NDCG的Lambda Loss
模型轻量化
- 裁剪、蒸馏、低精度量化