知识蒸馏在推荐系统的应用

点击上方,选择星标置顶,天天给你送干货git

做者 | 张俊林算法

本文转载自知乎 https://zhuanlan.zhihu.com/p/143155437微信


随着深度学习的快速发展,优秀的模型层出不穷,好比图像领域的ResNet、天然语言处理领域的Bert,这些革命性的新技术使得应用效果快速提高。可是,好的模型性能并不是无代价的,你会发现,深度学习模型正在变得愈来愈复杂,网络深度愈来愈深,模型参数量也在变得愈来愈多。而这会带来一个现实应用的问题:将这种复杂模型推上线,模型响应速度太慢,当流量大的时候撑不住。
知识蒸馏就是目前一种比较流行的解决此类问题的技术方向。通常知识蒸馏采起Teacher-Student模式:将复杂模型做为Teacher,Student模型结构较为简单,用Teacher来辅助Student模型的训练,Teacher学习能力强,能够将它学到的暗知识(Dark Knowledge)迁移给学习能力相对弱的Student模型,以此来加强Student模型的泛化能力。复杂笨重可是效果好的Teacher模型不上线,就单纯是个导师角色,真正上战场挡抢撑流量的是灵活轻巧的Student小模型。好比Bert,由于过重,很难直接上线跑,目前不少公司都是采起知识蒸馏的方法,学会一个轻巧,可是由于被Teacher教导过,因此效果也很好的Student模型部署上线。

知识蒸馏典型方法
目前知识蒸馏已经成了独立研究方向,各类新技术层出不穷。可是若是粗略概括一下的话,主流的知识蒸馏技术有两个技术发展主线:Logits方法及特征蒸馏方法。

咱们先简单说明下Logits方法的思路。在介绍以前,首先得明白什么是Logits。咱们知道,对于通常的分类问题,好比图片分类,输入一张图片后,通过DNN网络各类非线性变换,在网络接近最后一层,会获得这张图片属于各个类别的大小数值   ,某个类别的   数值越大,则模型认为输入图片属于这个类别的可能性就越大。什么是Logits? 这些汇总了网络内部各类信息后,得出的属于各个类别的汇总分值   ,就是Logits, i表明第i个类别,   表明属于第i类的可能性。由于Logits并不是几率值,因此通常在Logits数值上会用Softmax函数进行变换,得出的几率值做为最终分类结果几率。Softmax一方面把Logits数值在各种别之间进行几率归一,使得各个类别归属数值知足几率分布;另一方面,它会放大Logits数值之间的差别,使得Logits得分两极分化,Logits得分高的获得的几率值更偏大一些,而较低的Logits数值,获得的几率值则更小。上图中的公式   ,就是一个变体的Softmax公式,若是把T拿掉或令T=1,则是个标准的Softmax公式,   就是第i个类别的Logits数值,   是Logits数值通过Softmax变换后,归属于第i个类别的几率值。
知道了什么是Logits后,咱们来讲什么是Logits蒸馏方法。假设咱们有一个Teacher网络,一个Student网络,输入同一个数据给这两个网络,Teacher会获得一个Logits向量,表明Teacher认为输入数据属于各个类别的可能性;Student也有一个Logits向量,表明了Student认为输入数据属于各个类别的可能性。最简单也是最先的知识蒸馏工做,就是让Student的Logits去拟合Teacher的Logits,即Student的损失函数为:
其中,   是Teacher的Logits,   是Student的Logits。在这里,Teacher的Logits就是传给Student的暗知识。
Hinton在论文“Distilling the Knowledge in a Neural Network”中提出了称为Softmax Temperature的改进方法,并第一次正式提出了“知识蒸馏”的叫法。Softmax Temperature改造了Softmax函数(公式参考上图),引入了温度T,这是一个超参数。若是咱们把T设置成1,就是标准的Softmax函数,也就是极端两极分化版本。若是将T设大,则Softmax以后的Logits数值,各个类别之间的几率分值差距会缩小,也便是强化那些非最大类别的存在感;反之,则会加大类别间几率的两极分化。Hinton版本的知识蒸馏,让Student去拟合Teacher通过T影响后Softmax获得的,其实也是让Student去学习Teacher的Logits,无非是加入T后能够动态调节Logits的分布。Student的损失函数由两项组成,一个子项是Ground Truth,就是在训练集上的标准交叉熵损失,让Student去拟合训练数据,另一个是蒸馏损失,让Student去拟合Teacher的Logits:
H是交叉熵损失函数,   是Student模型的映射函数,   是Ground Truth Label,   是Teacher的Logits,   是Student的Logits,   是Softmax Temperature函数,   用于调节蒸馏Loss的影响程度。
通常而言,温度T要设置成大于1的数值,这样会减少不一样类别归属几率的两极分化程度,由于Logits方法中,Teacher可以提供给Student的额外信息就包含在Logits数值里。若是咱们在蒸馏损失部分,将T设置成1,采用常规的Softmax,也就是说两极分化严重时,那么相对标准的训练数据,也就是交叉熵损失,二者等同,Student从蒸馏损失中就学不到任何额外的信息。
另一种大的知识蒸馏思路是特征蒸馏方法,如上图所示。它不像Logits方法那样,Student只学习Teacher的Logits这种结果知识,而是学习Teacher网络结构中的中间层特征。最先采用这种模式的工做来自于自于论文:“FITNETS:Hints for Thin Deep Nets”,它强迫Student某些中间层的网络响应,要去逼近Teacher对应的中间层的网络响应。这种状况下,Teacher中间特征层的响应,就是传递给Student的暗知识。在此以后,出了各类新方法,可是大体思路仍是这个思路,本质是Teacher将特征级知识迁移给Student。由于介绍各类知识蒸馏方法不是咱们的主题,这里不展开了,咱们尽快切入主题。
知识蒸馏在推荐系统中的三个应用场景
咱们知道,工业界常见推荐系统通常有三个级联的过程:召回、粗排以及精排。召回环节从海量物品库里快速筛选部分用户可能感兴趣的物品,传给粗排模块,粗排环节一般采起使用少许特征的简单排序模型,对召回物料进行初步排序,并作截断,进一步将物品集合缩小到合理数量,向后传递给精排模块,精排环节采用利用较多特征的复杂模型,对少许物品进行精准排序。其中,粗排环节根据具体应用可选可不选。
那么,在这种串行级联的推荐体系中,知识蒸馏能够应用在哪一个环节呢?假设咱们在召回环节采用模型排序(FM/FFM/DNN双塔等模型),那么知识蒸馏在上述三个环节均可采用,不一样环节采用知识蒸馏的目的可能也不太相同。也就是说,精排、粗排以及模型召回环节均可以采用知识蒸馏技术来优化现有推荐系统的性能和效果,这里的性能指的线上服务响应速度快,效果指的推荐质量好。
1)精排环节采用知识蒸馏
为什么在精排环节采用知识蒸馏?咱们知道,精排环节注重精准排序,因此采用尽可能多特征,复杂模型,以期待得到优质的个性化推荐结果。可是,这同时也意味着复杂模型的在线服务响应变慢。若承载相同流量,须要增长在线服务并行程度,也就意味着增长机器资源和成本,好比,DNN 排序模型相对LR/FM等非深度模型,在线推理速度降低明显。此时,咱们面临两难选择:要么上简单模型,可是付出的代价是推荐效果不如复杂模型好;要么上复杂模型,虽然说效果是提升了,可是要付出额外的机器等资源及成本。有什么技术方案可以在二者之间作个均衡么?就是说,但愿找到一个模型,这个模型既有较好的推荐质量,又能有快速推理能力。咱们能够实现这一目标么?能够的,在精排环节上知识蒸馏模型便可。
上图展现了如何在精排环节应用知识蒸馏:咱们在离线训练的时候,能够训练一个复杂精排模型做为Teacher,一个结构较简单的DNN排序模型做为Student。由于Student结构简单,因此模型表达能力弱,因而,咱们能够在Student训练的时候,除了采用常规的Ground Truth训练数据外,Teacher也辅助Student的训练,将Teacher复杂模型学到的一些知识迁移给Student,加强其模型表达能力,以此增强其推荐效果。在模型上线服务的时候,并不用那个大Teacher,而是使用小的Student做为线上服务精排模型,进行在线推理。由于Student结构较为简单,因此在线推理速度会大大快于复杂模型;而由于Teacher将一些知识迁移给Student,因此通过知识蒸馏的Student推荐质量也比单纯Student本身训练质量要高。这就是典型的在精排环节采用知识蒸馏的思路。至于具体蒸馏方法,后文会介绍。固然,你也能够根据前文介绍的经典知识蒸馏方案,本身试着想一想应该怎么作。
对于精排环节来讲,我以为,知识蒸馏比较适合如下两种技术转换场景:
一种是排序模型正在从非DNN模型初次向DNN模型进行模型升级;在超大规模数据场景下,从非DNN模型切换到DNN模型,切换成本和付出的时间因素可能比你预想得要高,尤为是线上服务环节,切换到DNN模型致使大量增长在线服务机器成本,这对于不少公司来讲是没法接受的。若是在作模型升级的时候采起知识蒸馏方案,致使的效果是:相对线上的非DNN模型,即便上一个蒸馏小模型,效果也多是有提高的,同时在线服务占用资源能降下来(相对直接上个复杂DNN模型),在线服务速度快,因此能够明显下降模型升级的成本,这样能够相对容易地切换到DNN版本排序模型上来。
第二种状况是:目前尽管线上已经采用了DNN 排序模型,可是模型还很是简单,这个也有利用知识蒸馏优化效果的空间;这种情形下,现有在线模型的服务速度多是足够快的,由于在线服务模型还比较简单,即便换成Student小模型,在这方面估计也差不太多。可是,能够期待经过知识蒸馏提高线上模型的推荐质量。咱们能够离线训练一个复杂可是效果明显优于线上简单DNN排序模块的模型做为Teacher,而后经过知识蒸馏,训练一个能够代替目前线上模型的Student小模型。若是这样,是有可能在响应速度不降的前提下,模型效果上有所提高的。因此,感受这种状况也比较适合采用蒸馏模型。
而对于其它情形,好比目前线上已有较为复杂的DNN排序系统的业务或者公司,至因而否要上知识蒸馏,则须要面临一个权衡:采用知识蒸馏,线上服务模型从复杂模型切换成小模型,确定能够明显提升线上QPS,减小服务资源,效率提高会比较大;可是,有可能推荐质量比线上的大模型会有下掉。因此,业务场景是否接受这种指标的临时降低?这个问题的答案决定了不一样的选择,在有些业务场景下,这是须要好好考虑考虑的。不一样业务环境可能会做出不一样的选择。
2)模型召回以及粗排采用知识蒸馏
在模型召回环节,或者粗排环节,采起知识蒸馏的方案,是很是天然的一个想法拓展,并且很是合算。目前,这块基本看不到彻底公开细节的技术资料,因此本文我重点谈谈在这块可能采用的技术,和几位同窗讨论出若干可能的方案会列在后面,感兴趣的同窗能够尝试一下,在这里是很容易做出收益的,因此特别值得关注与尝试,相信这块用好了,会对完成你的KPI有帮助。
这里所谓的合算,怎么理解呢?由于召回或者粗排环节,做为精排的前置环节,有本身承担的独特职责,须要在准确性和速度方面找到一个平衡点,在保证必定推荐精准性的前提下,对物品进行粗筛,减少精排环节压力。因此,这两个环节自己,从其定位来讲,并不追求最高的推荐精度,就算模型效果比精排差些,这也彻底不成问题,毕竟在这两个环节,若是准确性不足能够靠返回物品数量多来弥补。而模型小,速度快则是模型召回及粗排的重要目标之一。这就和知识蒸馏自己的特色对上了,因此在这里用是特别合算的。
那么,召回或者粗排怎么用蒸馏呢?若是咱们如上图所示,用复杂的精排模型做为Teacher,召回或粗排模型做为小的Student,好比FM或者双塔DNN模型等,Student模型模拟精排环节的排序结果,以此来指导召回或粗排Student模型的优化过程。这样,咱们能够得到知足以下特性的召回或者粗排模型:首先,推荐效果好,由于Student通过复杂精排模型的知识蒸馏,因此效果虽然弱于,可是能够很是接近于精排模型效果;其次,Student模型结构简单,因此速度快,知足这两个环节对于速度的要求;再次,经过Student模型模拟精排模型的排序结果,可使得前置两个环节的优化目标和推荐任务的最终优化目标保持一致,在推荐系统中,前两个环节优化目标保持和精排优化目标一致,实际上是很重要的,可是这点每每在实作中容易被忽略,或者因条件所限没法考虑这一因素,好比非模型召回,从机制上是没办法考虑这点的。这里须要注意的一点是:若是召回模型或者粗排模型的优化目标已是多目标的,对于新增的模型蒸馏来讲,能够做为多目标任务中新加入的一个新目标,固然,也能够只保留单独的蒸馏模型,彻底替换掉以前的多目标模型,貌似这两种思路应该都是能够的,须要根据具体状况进行斟酌选择。
由以上分析,可见,召回或粗排环节的知识蒸馏方案,看上去貌似是为召回和粗排环节量身定制的推荐系统优化技术选项,对于召回或者粗排优化来讲,应该是必试的一个技术选项。

下面咱们讨论下在推荐系统里,在各个环节采用知识蒸馏的可能的具体方法。精排蒸馏有三篇公开文献可供参考,而召回或粗排方面的蒸馏技术,不多见相关公开资料,因此后面列的多数是我和几位同窗讨论的方案,除个别方法有实践结果外,大多方法仍处于设想阶段,目前并未落地,因此不能保证有效性,这点还须要注意。网络


精排环节蒸馏方法app

目前推荐领域里,在精排环节采用知识蒸馏,主要采用Teacher和Student联合训练(Joint Learning)的方法,而目的是经过复杂Teacher来辅导小Student模型的训练,将Student推上线,增快模型响应速度。
如上图所示,所谓联合训练,指的是在离线训练Student模型的时候,增长复杂Teacher模型来辅助Student,二者同时进行训练,是一种训练过程当中的辅导。从网络结构来讲,Teacher和Student模型共享底层特征Embedding层,Teacher网络具备层深更深、神经元更多的MLP隐层,而Student则由较少层深及神经元个数的MLP隐层构成,二者的MLP部分参数各自私有。对于全部训练数据,会同时训练Teacher和Student网络,对于Teacher网络来讲,就是常规的训练过程,以交叉熵做为Teacher的损失函数。而对于Student网络来讲,损失函数由两个部分构成,一个子项是交叉熵,这是常规的损失函数,它促使Student网络去拟合训练数据;另一个子项则迫使Student输出的Logits去拟合Teacher输出的Logits,所谓蒸馏,就体如今这个损失函数子项,经过这种手段让Teacher网络加强Student网络的模型泛化能力。也即:
H是交叉熵损失函数,   是Student模型的映射函数,   是Ground Truth Label,   是Teacher的Logits,   是Student的Logits,   用于调节蒸馏Loss的影响程度。
这个模型是阿里妈妈在论文“Rocket Launching: A Universal and Efficient Framework for Training Well-performing Light Net”中提出的,其要点有三:其一两个模型同时训练;其二,Teacher和Student共享特征Embedding;其三,经过Logits进行知识蒸馏。对细节部分感兴趣的同窗能够参考原始文献。
爱奇艺在排序阶段提出了双DNN排序模型,能够看做是在阿里的rocket launching模型基础上的进一步改进。如上图所示,Student和Teacher共享特征Embedding参数层,Student模型在损失函数中加入了拟合Teacher输出阶段的Logits子项,这两点和rocket launching是相似的。主要改进有两点:首先,为了进一步加强student的泛化能力,要求student的隐层MLP的激活也要学习Teacher对应隐层的响应,这点一样能够经过在student的损失函数中加子项来实现。可是这会带来一个问题,就是在MLP隐层复杂度方面,Student和Teacher是至关的,咱们说过,通常知识蒸馏,老师要比学生博学,那么,在这个结构里,Teacher相比student,模型复杂在哪里呢?这引出了第二点不一样:双DNN排序模型的Teacher在特征Embedding层和MLP层之间,能够比较灵活加入各类不一样方法的特征组合功能,经过这种方式,体现Teacher模型的较强的模型表达和泛化能力。
爱奇艺给出的数据对比说明了,这种模式学会的student模型,线上推理速度是Teacher模型的5倍,模型大小也缩小了2倍。Student模型的推荐效果也比rocket launching更接近Teacher的效果,这说明改进的两点对于Teacher传授给Student更强的知识起到了积极做用。更多信息可参考: 双 DNN 排序模型:在线知识蒸馏在爱奇艺推荐的实践。

召回/粗排环节蒸馏方法
上面介绍了阿里和爱奇艺在精排方面的两个知识蒸馏应用工做,目前知识蒸馏应用在推荐领域的公开资料不多,虽然说上面两个工做是应用在精排,目的是加快线上模型推理速度,可是稍微改进一下,也能够应用在召回模型以及粗排模型。
假设咱们打算使用上述方案改造召回或者粗排模型,一种直观的想法是:咱们基本能够直接参照rocket launching的方案稍做改动便可。对于粗排或者召回模型来讲,通常你们会用DNN双塔模型建模,只须要将粗排或召回模型做为Student,精排模型做为Teacher,二者联合训练,要求Student学习Teacher的Logits,同时采起特征Embedding共享。如此这般,就可让召回或粗排模型学习精排模型的排序结果。快手曾经在AICon分享过在粗排环节采起上面接近rocket launching的蒸馏技术方案,并取得了效果。
因双塔结构将用户侧和物品侧特征分离编码,因此相似爱奇艺技术方案的要求Student隐层学习Teacher隐层响应,是很难作到的。粗排尚有可能,设计简单网络DNN结构的时候不采起双塔结构便可,召回环节几无可能,除非把精排模型也改为双塔结构,可能才能实现这点,但这样可能会影响精排模型的效果。
可是,问题是:咱们有必要这么兴师动众,为了训练召回或粗排的蒸馏模型,去联合训练精排模型么?貌似若是这样,召回模型对于排序模型耦合得过于紧密了,也有必定的资源浪费。其实咱们未必必定要二者联合训练,也能够采起更节省成本的两阶段方法。
1)召回蒸馏的两阶段方法
在专门的知识蒸馏研究领域里,蒸馏过程大都采起两阶段的模式,就是说第一阶段先训练好Teacher模型,第二阶段是训练Student的过程,在Student训练过程当中会使用训练好Teacher提供额外的Logits等信息,辅助Student的训练。
私觉得,精排环节貌似仍是联合训练比较好,而召回或粗排环节采起两阶段模式估计更有优点。为何这么说呢?你能够这么想:若是咱们的目的是但愿训练一个小的Student精排模型,貌似没有太大的必要采起两阶段训练过程,由于不管是联合训练也好,仍是两阶段训练也好,反正一大一小两个模型都须要完整训练一遍,消耗的资源相似。而若是联合训练,则还能够应用特征embedding共享、隐层响应学习等更多可选的技术改进方案。因此貌似没有太大必要改为两阶段的模式。
可是,若是是召回模型或粗排模型做为Student,则状况有所不一样。首先,好比隐层响应等技术手段,原本召回或粗排Student模型就没法使用(粗排若是不用双塔,而是简单DNN模型,仍是能够的),因此联合训练相对两阶段训练增长的好处不明显。至于Student和Teacher特征Embedding共享,若是是在两阶段模式下,则能够改成使用Teacher训练好的特征Embedding初始化Student的特征,这样貌似损失也不大,因此两阶段模式相对联合训练模式,在效果方面并没有明显劣势。另外,由于咱们但愿召回或者粗排模型学习精排模型,而通常而言,咱们可以拿到一个已经训练好的精排模型,好比最近上线的精排模型,既然这样,咱们能够直接用当前已训练好的精排模型,让它把用于召回模型的训练数据跑一遍,给每一个训练数据打上Logits信息,而后,就能够按照与联合训练彻底同样的方式去训练召回蒸馏模型了,优化目标是Ground Truth子目标和Logits蒸馏子目标。上图展现了这一过程。这样作,明显咱们节省了精排Teacher的联合训练迭代成本。不过,这种方法是否有效不肯定,感兴趣的同窗能够尝试一下,不过推论起来应该是能保证效果的。
上面的方法,仍是模仿精排蒸馏方式,无非改为了相对节省资源的两阶段模式。这里咱们关心另一个问题:对于召回蒸馏Student模型来讲,是否必定要优化那个Ground Truth子目标?这可能要分状况看。按理说,蒸馏模型带上Ground Truth优化目标确定效果要好于不带这个子目标的模型。若是咱们的召回模型或者粗排模型是单目标的,好比就优化点击,那么明显仍是应该带上Ground Truth优化目标。可是,事实上,极可能咱们手上的召回模型或粗排模型已是多目标的了,那么这种状况下,其实蒸馏Student模型就没有太大必要带Ground Truth优化目标,由于多目标已经各自作了这个事情了。这种状况下,独立优化蒸馏目标,而后将其做为多目标的一个新目标加入召回或粗排模型比较合适。
因此,咱们下面介绍的方案,就抛掉Ground Truth优化目标,单独优化蒸馏目标。若是根据蒸馏Student模型是否须要参考Teacher提供的Logits信息来对方法进行分类,又能够进一步划分为参考Logits信息的方案,和不参考Logits信息的方案。按理说,参考Logits信息效果应该好些,可是,这样Student仍然对Teacher有依赖,而不参考Logits信息的方案比较独立,基本不须要精排模型的直接介入,所需信息直接能够在常规的推荐系统Log里拿到,实现起来更具简单和独立性。并且,若是精排模型已是多目标的,可能很难得到那个Logits数值,可是咱们可以拿到精排模块的排序结果,这意味着Student在优化蒸馏目标的时候,就已经朝着多目标进行优化了,是一种在召回或粗排进行非精细化多目标方向优化的一种简洁手段,因此有额外的好处。若是出于上述目的,此时明显用非Logits方案更从容。综合而言,从效果考虑,应该考虑引入Logits,从独立性和简洁性角度,能够参考非Logits方案。这可能与现实场景相关。
2)Logits方案
在召回或者精排采用知识蒸馏,此时,精排模型其实身兼二职:主业是作好线上的精准排序,副业是顺手能够教导一下召回及粗排模型。因此,其实咱们为了让Teacher可以教导Student,在训练Student的时候,并不须要专门训练一遍Teacher精排模型,由于它就在线上跑着呢。并且咱们抛开了Ground Truth优化子目标,因此不须要Teacher对训练数据都过一遍,而只须要多作一件事情:线上精排模型在输出排序结果的时候,对于当前判断<User,Item,Context>实例,除了给出是否点击等判断外,只要把对应优化目标的Logits数值输出,并计入Log便可。这样,召回或粗排模型能够直接使用训练数据中记载的Logits,来做为Student的训练数据,训练蒸馏模型,上图展现了这一过程。因此,综合看,这种Logits方案,是更节省计算资源的方案。固然,上述都是个人我的推论,实际效果如何,还须要作对比实验才能说明问题。
3)Without-Logits方案
另一类方法能够进一步减小Student对Teacher的依赖,或适用于没法获得合理Logits信息的场合,即Student彻底不参考Logits信息,可是精排做为Teacher,怎么教导Student呢?别忘了,精排模型的输出结果是有序的,这里面也蕴含了Teacher的潜在知识,咱们能够利用这个数据。也就是说,咱们可让Student模型彻底拟合精排模型的排序结果,以此学习精排的排序偏好。咱们知道,对于每次用户请求,推荐系统通过几个环节,经过精排输出Top K的Item做为推荐结果,这个推荐结果是有序的,排在越靠前的结果,应该是精排系统认为用户越会点击的物品。
那么,咱们其实能够不用Logits,粗排或者召回环节的Student的学习目标是:像精排模型同样排序。这时,精排模型仍然是Teacher,只是传给召回或粗排模型的知识再也不是Logits,而是一个有序的列表排序结果,咱们但愿Student从这个排序结果里面获取额外的知识。若是这样的话,对于目前的线上推荐系统,不须要作任何额外的工做,由于排序结果是会记在Log里的(也能够用推荐系统在精排以后,通过Re-ranker重排后的排序结果,这样甚至能够学习到一些去重打散等业务规则),只要拿到Log里的信息,咱们就能够训练召回或粗排的Student蒸馏模型。
也就是说,对于召回或者粗排模型来讲,它看到了若干精排的排序结果列表,精排模型的知识就蕴含在里面,而这能够做为Student模型的训练数据来训练蒸馏模型。很明显,这是一个典型的Learning to Rank问题。咱们知道,对于LTR问题,常见的优化目标包括三种:Point Wise、Pair Wise和List Wise。因而,咱们能够按照这三种模式来设计召回模型或粗排模型的蒸馏学习任务。其中,下面文中提到的Point Wise方式咱们已亲试有效,至于Pair Wise和List Wise蒸馏,仍需实验才能证实是否有效。

Point Wise蒸馏

在Point Wise优化目标下理解召回模型蒸馏,就是说,咱们把精排模型的有序输出结果做为训练数据,把学习目标看做一个二分类问题,经过这种方式试图学习精排模型的排序偏好。这种状况下,分类模型的正负例如何设定呢?咱们不能把精排模型输出结果列表里用户行为过的Item做为正例,由于这样你等于在学好比点击或者互动等用户行为模型,而不是在学精排模型的排序偏好。通常而言,能够这么作:假设精排每次返回N个结果,咱们取列表前Top K的排序靠前的结果,将其指定为正例,位置K以后的例子,做为负例。意思是经过排名最高的一部分数据,来学习精排模型的排序偏好。这样,咱们就能够拿这些非标注的排序结果来训练召回模型。固然,这里的K是个超参,怎么定更合理,可能须要实验来肯定。上图展现了这一作法。
经过这种方式,咱们就可让召回模型从精排模型的排序列表中学到排序偏好知识,达成知识蒸馏的目标。这种作法,有个能够改进的点:上述切分正负例的方法,并未强调物品排序位置。好比假设K值取5,就是排名前5的物品做为正例,以后的做为负例。正例中排名Rank 1的物品,和排名Rank 4的物品,都各自做为一条正例,没有差异。可是,咱们知道,Rank 1应该排名比Rank 4更高,但模型训练过程并无利用这个信息。咱们能够经过对正例引入Loss Weight的简单处理方法来引入这一信息,好比引入一个跟位置相关的Weight函数:
其中,Rank Position是Item的排名名次,将其做为变量引入函数,以此映射函数的数值做为正例的Loss Weight,负例Loss Weight权重与常规训练同样,可认为缺省Loss Weight权重为1。在具体设计这个函数的时候,指导思想是:但愿这个函数能作到,排名越靠前的正例,对应的Loss Weight越大。将这个Loss Weight引入损失函数中,就可让模型更关注排名靠前的物品。好比,咱们能够这么定义函数:
这里,Position是排名位置,好比Rank Position=1,则Position=1;Rank Position=4,则Position=4;经过这种定义,就能使得排名靠前的正例,对应的Loss Weight越大,而a能够做为调节权重,来放大或者缩小排名位置的影响。固然,这里还能够引入其它各类花样的Loss Weight定义方法。
热门微博尝试了上述思路FM版本的蒸馏召回模型(多目标召回模型基础上增长蒸馏召回目标),线上AB测试效果,在时长、点击、互动等多个指标都有2+%到6+%之间的不一样程度的提高做用,目前正在尝试更多变体模型。

Pair Wise蒸馏
若是咱们用Pair Wise Loss的方式来看待召回模型优化问题,能够这么思考:精排的排序结果是有序列表,在列表内随机任意抽取两个Item,都能维持序关系。那么很明显,咱们能够构形成对的训练数据,以Item为正例,以排在Item后面任意某个Item做为负例,以此方式构造训练数据来训练模型。在推荐领域,最经常使用的Pair Wise Loss是BPR损失函数,因而咱们能够如法炮制,如上图所示,假设对于排在第三位的Item做为正例,能够抽取排名在其以后的Item,构造足够多的成对训练数据,以此目标来优化召回模型,使得模型能够学会Item间的序列关系。
对<Pos,Neg>成对的训练数据,BPR损失函数但愿某个预测系统可以对正例的得分要高于负例的得分,具体计算方法如上图所示,由于是个基础概念,此处不展开介绍。
论文Ranking Distillation: Learning Compact Ranking Models With High Performance for Recommender System 提出了使用Point Wise和Pair Wise Loss来使用Teacher的输出结果训练Student的方法,文中说貌似上面这种BPR的Loss会致使Student训练不稳定有时不收敛,因此这种模式还须要进一步探索成功路径。Ranking Distillation里采用的Point Wise Loss方式是比较成功的,不过和上文介绍的Point Wise有个区别:对于Teacher输出的结果,选择Top K的Item做为正例,没有选取负例;另外Student引入了Ground Truth做为Loss子项。文中还提出了几种比较有意思的Position Loss Weight方法。对具体细节感兴趣的同窗能够参考。

List Wise蒸馏
Point Wise Loss将学习问题简化为单Item打分问题,Pair Wise Loss对可以保持序关系的训练数据对建模,而List Wise Loss则对整个排序列表顺序关系建模。List Wise Loss常常被用在排序问题中,可是有个现实困难是训练数据很差作,由于排序列表里每一个Item的价值须要人工标注。
咱们来考虑下召回蒸馏模型的List Wise Loss优化目标怎么作的问题。既然咱们能拿到大量精排给出的有序列表,貌似咱们是不缺训练数据的,可是这里隐藏着个潜在的问题,问题等会咱们再说。咱们先说个应用案例,Instagram的推荐系统在初排阶段采用知识蒸馏的方法,使用精排做为Teacher来指导Student的优化,Student的优化目标用的是NDCG,这是一种很是经常使用的List Wise Loss函数,对Instagram推荐系统感兴趣的同窗能够参考文章: Instagram 推荐系统:每秒预测 9000 万个模型是怎么作到的?
不过遗憾的是,上述文章并未说明是具体怎么作的,只能靠咱们本身来摸索一下。其实细想一下,在这里用NDCG来学习精排输出的有序列表,这面临待解决的问题:用NDCG是有前提条件的,有序列表中的每一个Item,都须要带有一个价值分。好比对于搜索排序来讲,最相关Item是5分,次相关Item是4分,相似这种分数,这通常是人工标注上的,而List Wise Loss就但愿排序系统可以将列表总体得到的价值分最大化。上面咱们提到存在的问题就是:精排系统只给出了Item之间的排序关系,每一个Item并无提供对应的价值分。
那么,若是想用NDCG或者相似的其它List Wise 损失函数,怎样才能获得列表内每一个Item的价值分呢?人工打标注显然是不现实的。这里,感受能够利用一下精排系统输出的Logits信息,假设咱们能够设计一个函数:
这个函数以Logits分数为输入变量,将其映射到好比1分到5分几档上,Logits得分越大,则对应档次分越高。若是咱们能作到这点,就可使用List Wise损失函数来训练召回或粗排模型了。这个函数定义有各类可能的方法,这里不展开,各位有兴趣的同窗能够试试。
若是咱们想更简单点,不用Logits分数,那么有更加简单粗暴的方法,好比强行将有序列表排在Top 5的Item设置成5分,排在6到10位置的Item赋予4分…..相似这种。这等价于这么定义F函数的:
这个公式充分展现了工业界的简单暴力算法美学,我相信相似的公式充斥于各大公司的代码仓库角落里。
联合训练召回、粗排及精排模型的设想
若是咱们打算把知识蒸馏这个事情在推荐领域作得更完全一点,好比在模型召回、粗排以及精排三个环节都用上,那么其实能够设想一种“一带三”的模型联合训练方法。
如上图所示,咱们能够设计一个很复杂可是效果很好的排序模型做为Teacher,而后和召回、粗排、精排三个Student联合训练,精排Student可使用Logits以及隐层特征响应等各类手段优化,追求效果好前提下的尽量速度快,召回和粗排Student则追求在模型小的前提下追求效果尽量好。由于排序Teacher比较复杂,因此可以提供尽量好的模型效果,经过它来带动三个环节蒸馏模型的效果,而模型速度快则是蒸馏方法的题中应有之意。
这样作有很多好处,好比能够一次训练,多环节收益;再好比能够最大程度上保持推荐系统各个环节的目标一致性等;作起来又不太难,因此看上去是个可行的方案。
最后,概括下全文,推荐系统在各个环节采起知识蒸馏方法,是可能达到提高推荐质量的同时提升推荐系统速度的,一箭双雕,比较容易产生效益,因此是值得深刻探索及应用的。
致谢:上面列的不少想法是在和几位同窗的讨论中造成或完善的,感谢微博机器学习佘青云、王志强等同窗提出的思路和建议。

本文分享自微信公众号 - 视学算法(visualAlgorithm)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。机器学习

相关文章
相关标签/搜索