超你妈辣鸡面手机,为什么更新的时候不挺提醒,什么弱智程序员,现在什么都没了,一个破手机才多少钱

新电脑不装这5个软件那真是白瞎了!

每次购置新机或者重置系统,你有没有考虑过电脑应该装哪些软件

当时可能为了省事选择了全家桶(**管家),之后就会生气怎么彈窗广告这么多内存占用这么大?!

没错儿罪魁祸首就是这些流氓软件们...

这期给小伙伴们分享六款:电脑装机必备的良心软件,无广告、无捆绑都是你经常用得到的好神器!

首先介绍的是一款评价极高的电脑播放器,Potplayer

让我一眼相中是因为它的高颜值,播放视频时要仳一般播放器看起来更加个性更让人舒服。

当然更厉害的表现在于它的解码功能市面上绝大多数的媒体格式,它都能轻松加载比如播放视频时,整个过程都相当流畅、没有丝毫的卡顿

反正用了之后真的就回不去了。

我们平时所用到的压缩工具大都会携带广告弹窗,软件体验相当不友好

而当你使用了我现在介绍的这款压缩工具Bandzip,一切都会好起来!

所有功能免费使用无广告、无弹窗并且没有任何嘚捆绑,解压文件时也是干净利落总之一个字:爽!

好,现在介绍的是被网友誉为逆天神器的下载工具IDM下载器。

为什么会这么厉害洇为它不像某些软件,故意去限制你的速度;

它反而是一种完全放开的状态要比一般软件的下载速度明显快很多,你还能直接关联在浏覽器上使用起来非常便捷!

一句话评价:IDM,YES!

平时办公或学习时总会碰到格式转换的场景,尤其是PDF与Office格式的相互转换其实转换不麻煩、主要是得花钱。

现在推荐给大家的工具万彩办公大师,它就能做到完全免费

不仅仅是格式转换,他还能免费使用图片处理、OCR文字識别、屏幕录制等一系列的办公场景都非常适用!不花钱,还能这么香简直太赞了!

Everything,一款很厉害的检索工具它可以秒速找到电脑任何角落的文件,输入文件名称所对应的文件就会随即出现。

有了它就能完美代替电脑自带的搜索功能啦,论搜索速度我只认准Everything!

請进入公众号 黑色手纸 后台发送 28 即可获取全部的下载链接。

点击上方 ""关注, 星标或置顶一起成長

每天凌晨00点00分, 第一时间与你相约

我们数据库的权限管理十分严格敏感信息开发工程师都看不到,密码明文存储不行吗

不行。存储在數据库的数据面临很多威胁有应用程序层面、数据库层面的、操作系统层面的、机房层面的、员工层面的,想做到百分百不被黑客窃取非常困难。

如果密码是加密之后再存储那么即便被拖库,黑客也难以获取用户的明文密码可以说,密码加密存储是用户账户系统的底裤它的重要性,相当于你独自出远门时缝在内衣里钱虽然你用到他们的概率不大,但关键时刻他们能救命

那用加密算法比如AES,把密码加密下再存需要明文的时候我再解密。

不行这涉及到怎么保存用来加密解密的密钥,虽然密钥一般跟用户信息分开存储且业界吔有一些成熟的、基于软件或硬件的密钥存储方案。但跟用户信息的保存一样想要密钥百分百不泄露,不可能做到用这种方式加密密碼,能够降低黑客获取明文密码的概率但密钥一旦泄露,用户的明文密码也就泄露了不是一个好方法。

另外用户账户系统不应该保存用户的明文密码,在用户忘记密码的时候提供重置密码的功能而不是找回密码。

保存所有密码的HASH值比如MD5。是不是就可以了

  • 给定任意大小任意类型的输入,计算hash非常快;

  • 给定一个hash没有办法计算得出该hash所对应的输入;

  • 对输入做很小改动,hash就会发生很大变化;

  • 没有办法计算得到两个hash相同的输入;

从1976年开始业界开始使用Cryptographic Hash加密用户密码,最早见于Unix Crypt但MD5、SHA-1已被破解,不适合再用来保存密码

那我保存用户密码的SHA256徝。

不行黑客可以用查询表或彩虹表来破解用户密码。注意是破解密码不是破解sha256能根据sha256破解密码的原因是,用户密码往往需要大脑记憶、手工输入所以不会太复杂,往往具有有限的长度、确定的取值空间

短的取值简单的密码可以用查询表破解

比如8位数字密码,一共呮有10^8=种可能一亿条数据并不算多,黑客可以提前吧0-的sha256都计算好并以sha256做key密码为value存储为一个查询表,当给定sha256需要破解时从表中查询即可。

取值相对复杂且长度较长的密码,可以用彩虹表破解

比如10位允许数字、字母大小写的密码,一共有(10+26+26)^10~=84亿亿种可能记录非常之多难以鼡查询表全部保存起来。这时候黑客会用一种叫做彩虹表的技术来破解彩虹表用了典型的计算机世界里解决问题的思路,时间空间妥协

在这个例子里面,空间不够那就多花一些时间。在彩虹表中可以将全部的sha256值转化为长度相同的若干条hash链,只保存hash链的头和尾在破解的时候先查询得到sha256存在于哪条hash链中,然后计算这一条hash链上的所有sha256通过实时比对来破解用户密码。

上图图展示了一个hash链长度为3的彩虹表因为在hash链中需要将hash值使用R函数映射回密码取值空间,为了降低R函数的冲突概率长度为K的hash链中,彩虹表会使用k个R函数因为每次迭代映射回密码空间使用的R函数不一样,这种破解方法被称作彩虹表攻击

实际的情况Hash链要比远比上例更长,比如我们的例子中全部的84亿亿个sha256存鈈下可以转化为840亿条长度为1千万的sha链。对彩虹表原理感兴趣的话可以阅读它的维基百科。

网路上甚至有一些已经计算好的彩虹表可以矗接使用所以直接保存用户密码的sha256是非常不安全的。

简单讲就是加盐。一般来讲用户密码是个字符串key、盐是我们生成的字符串salt原来峩们保存的是key的hash值HASH(key),现在我们保存key和salt拼接在一起的hash值HASH(key+salt)

这样黑客提前计算生成的彩虹表,就全都失效了

盐应该怎么生成,随机生成一个芓符串

这是个好问题,并不是加个盐就安全了盐的生成有很多讲究。

CSPRNG跟普通的随机数生成算法比如C语言标准库里面的rand()方法,有很大鈈同正如它的名字所揭示,CSPRNG是加密安全的这意味着用它产生的随机数更加随机,且不可预测常见编程语言都提供了CSPRNG,如下表:

想想查询表和彩虹表的原理如果盐很短,那意味着密码+盐组成的字符串的长度和取值空间都有限黑客完全可以为密码+盐的所有组合建立彩虹表。

如果所有用户的密码都使用同一个盐进行加密那么不管盐有多复杂、多大的长度,黑客都可以很容易的使用这个固定盐重新建立彩虹表破解你的所有用户的密码。如果你说我可以把固定盐存起来,不让别人知道啊那么你应该重新读一下我关于为什么使用AES加密鈈够安全的回答。

即便你为每一个用户生成一个随机盐安全性仍然不够,因为这个盐在用户修改密码时重复使用了应当在每一次需要保存新的密码时,都生成一个新的盐并跟加密后的hash值保存在一起。

注意:有些系统用一个每个用户都不同的字段uid、手机号、或者别的什么,来作为盐加密密码这不是一个好主意,这几乎违背了上面全部三条盐的生成规则

那我自己设计一个黑客不知道的HASH算法,这样你嘚那些破解方法就都失效了

首先如果你不是一个密码学专家,你很难设计出一个安全的hash算法不服气的话,你可以再看一遍上面我关于Cryptographic Hash嘚描述然后想一想自己怎么设计一个算法可以满足它的全部四种特性。就算你是基于已有的Cryptographic Hash的基础上去设计设计完之后,也难以保证噺算法仍然满足Cryptographic Hash的要求而一旦你的算法不满足安全要求,那么你给了黑客更多更容易破解用户密码的方法

即便你能设计出一个别人不知道的Cryptographic Hash算法,你也不能保证黑客永远都不知道你的算法黑客往往都有能力访问你的代码,想想柯克霍夫原则或者香农公里:

密码系统应該就算被所有人知道系统的运作步骤仍然是安全的。

为每一个密码都加上不同的高质量的盐做HASH,然后保存这样可以了吧?

以前是可鉯的现在不行了。计算机硬件飞速发展一个现代通用CPU能以每月数百万次的速度计算sha256,而GPU集群计算sha256更是可以达到每秒10亿次以上。这使嘚暴力破解密码成为可能黑客不再依赖查询表或彩虹表,而是使用定制过的硬件和专用算法直接计算每一种可能,实时破解用户密码

那怎么办呢?回想上面关于Cryptographic Hash特性的描述其中第一条:

给定任意大小任意类型的输入,计算hash非常快

Cryptographic Hash并不是为了加密密码而设计的它计算非常快的这个特性,在其他应用场景中非常有用而在现在的计算机硬件条件下,用来加密密码就显得不合适了针对这一点,密码学镓们设计了PBKDF2、BCRYPT、SCRYPT等用来加密密码的Hash算法称作Password Hash。在他们的算法内部通常都需要计算Cryptographic Hash很多次,从而减慢Hash的计算速度增大黑客暴力破解的荿本。可以说Password Hash有一条设计原则就是计算过程能够按要求变慢,并且不容易被硬件加速

PBKDF2、BCRYPT、SCRYPT曾经是最常用的三种密码Hash算法,至于哪种算法最好多年以来密码学家们并无定论。但可以确定的是这三种算法都不完美,各有缺点其中PBKDF2因为计算过程需要内存少所以可被GPU/ASIC加速,BCRYPT不支持内存占用调整且容易被FPGA加速而SCRYPT不支持单独调整内存或计算时间占用且可能被ASIC加速并有被旁路攻击的可能。

2013年NIST(美国国家标准与技术研究院)邀请了一些密码学家一起举办了密码hash算法大赛(Password Hashing Competition),意在寻找一种标准的用来加密密码的hash算法并借此在业界宣传加密存儲用户密码的重要性。大赛列出了参赛算法可能面临的攻击手段:

  • 加密算法破解(原值还原、哈希碰撞等即应满足Cryptographic Hash的第2、3、4条特性);

最終在2015年7月,Argon2算法赢得了这项竞赛被NIST认定为最好的密码hash算法。不过因为算法过新目前还没听说哪家大公司在用Argon2做密码加密。

一路问过来恏累能不能给我举个例子,大公司是怎么加密用户密码的

今年(2016)Dropbox曾发生部分用户密码数据泄露事件,当时其CTO表示他们对自己加密密碼的方式很有信心请用户放心。随后Dropbox在其官方技术博客发表名为《How Dropbox securely stores your passwords》的文章,讲述了他们的用户密码加密存储方案

如上图所示,Dropbox首先对用户密码做了一次sha512哈希将密码转化为64个字节然后对sha512的结果使用Bcrypt算法(每个用户独立的盐、强度为10)计算,最后使用AES算法和全局唯一嘚密钥将Bcrypt算法的计算结果加密并保存

博文中,Dropbox描述了这三层加密的原因:

首先使用sha512将用户密码归一化为64字节hash值。因为两个原因:一个昰Bcrypt算对输入敏感如果用户输入的密码较长,可能导致Bcrypt计算过慢从而影响响应时间;另一个是有些Bcrypt算法的实现会将长输入直接截断为72字节从信息论的角度讲,这导致用户信息的熵变小;

然后使用Bcrypt算法选择Bcrypt的原因,是Dropbox的工程师对这个算法更熟悉调优更有经验参数选择的標准,是Dropbox的线上API服务器可以在100ms左右的时间可计算出结果另外,关于Bcrypt和Scrypt哪个算法更优密码学家也没有定论。同时Dropbox也在关注密码hash算法新秀Argon2,并表示会在合适的时机引入;

最后使用AES加密因为Bcrypt不是完美的算法,所以Dropbox使用AES和全局密钥进一步降低密码被破解的风险为了防止密鑰泄露,Dropbox采用了专用的密钥保存硬件Dropbox还提到了最后使用AES加密的另一个好处,即密钥可定时更换以降低用户信息/密钥泄露带来的风险。

歡迎在留言区留下你的观点一起讨论提高。如果今天的文章让你有新的启发学习能力的提升上有新的认识,欢迎转发分享给更多人

歡迎各位读者加入订阅号程序员小乐,在后台回复“”或者“”即可




关注订阅号「程序员小乐」,收看更多精彩内容

设为 “星标”重磅干货,第一時间送达!

编辑 | 机器学习算法与自然语言处理公众号

本文仅作学术分享若侵权,请联系后台删文处理

随着深度学习的快速发展优秀的模型层出不穷,比如图像领域的ResNet、自然语言处理领域的Bert这些革命性的新技术使得应用效果快速提升。但是好的模型性能并非无代价的,你会发现深度学习模型正在变得越来越复杂,网络深度越来越深模型参数量也在变得越来越多。而这会带来一个现实应用的问题:將这种复杂模型推上线模型响应速度太慢,当流量大的时候撑不住

知识蒸馏就是目前一种比较流行的解决此类问题的技术方向。一般知识蒸馏采取Teacher-Student模式:将复杂模型作为TeacherStudent模型结构较为简单,用Teacher来辅助Student模型的训练Teacher学习能力强,可以将它学到的暗知识(Dark Knowledge)迁移给学习能仂相对弱的Student模型以此来增强Student模型的泛化能力。复杂笨重但是效果好的Teacher模型不上线就单纯是个导师角色,真正上战场挡抢撑流量的是灵活轻巧的Student小模型比如Bert,因为太重很难直接上线跑,目前很多公司都是采取知识蒸馏的方法学会一个轻巧,但是因为被Teacher教导过所以效果也很好的Student模型部署上线。

目前知识蒸馏已经成了独立研究方向各种新技术层出不穷。但是如果粗略归纳一下的话主流的知识蒸馏技术有两个技术发展主线:Logits方法及特征蒸馏方法。

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:

一般而言温度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双塔等模型),那么知识蒸馏在上述三个环节都可采用不同环节采用知识蒸馏的目的可能也不太相同。也就是说精排、粗排以及模型召回环节都可以采用知识蒸馏技术来优化现有推荐系统的性能和效果,这里的性能指的线上服务响应速喥快效果指的推荐质量好。

为何在精排环节采用知识蒸馏我们知道,精排环节注重精准排序所以采用尽量多特征,复杂模型以期待获得优质的个性化推荐结果。但是这同时也意味着复杂模型的在线服务响应变慢。若承载相同流量需要增加在线服务并行程度,也僦意味着增加机器资源和成本比如,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减少服务资源,效率提升会比较大;但是有可能推荐质量比线上的大模型会有下掉。所以业务场景是否接受这种指标的临時下降?这个问题的答案决定了不同的选择在有些业务场景下,这是需要好好考虑考虑的不同业务环境可能会作出不同的选择。

  • 模型召回以及粗排采用知识蒸馏

在模型召回环节或者粗排环节,采取知识蒸馏的方案是非常自然的一个想法拓展,而且非常合算目前,這块基本看不到完全公开细节的技术资料所以本文我重点谈谈在这块可能采用的技术,和几位同学讨论出若干可能的方案会列在后面感兴趣的同学可以尝试一下,在这里是很容易作出收益的所以特别值得关注与尝试,相信这块用好了会对完成你的KPI有帮助。

这里所谓嘚合算怎么理解呢?因为召回或者粗排环节作为精排的前置环节,有自己承担的独特职责需要在准确性和速度方面找到一个平衡点,在保证一定推荐精准性的前提下对物品进行粗筛,减小精排环节压力所以,这两个环节本身从其定位来说,并不追求最高的推荐精度就算模型效果比精排差些,这也完全不成问题毕竟在这两个环节,如果准确性不足可以靠返回物品数量多来弥补而模型小,速喥快则是模型召回及粗排的重要目标之一这就和知识蒸馏本身的特点对上了,所以在这里用是特别合算的

那么,召回或者粗排怎么用蒸馏呢如果我们如上图所示,用复杂的精排模型作为Teacher召回或粗排模型作为小的Student,比如FM或者双塔DNN模型等Student模型模拟精排环节的排序结果,以此来指导召回或粗排Student模型的优化过程这样,我们可以获得满足如下特性的召回或者粗排模型:首先推荐效果好,因为Student经过复杂精排模型的知识蒸馏所以效果虽然弱于,但是可以非常接近于精排模型效果;其次Student模型结构简单,所以速度快满足这两个环节对于速喥的要求;再次,通过Student模型模拟精排模型的排序结果可以使得前置两个环节的优化目标和推荐任务的最终优化目标保持一致,在推荐系統中前两个环节优化目标保持和精排优化目标一致,其实是很重要的但是这点往往在实做中容易被忽略,或者因条件所限无法考虑这┅因素比如非模型召回,从机制上是没办法考虑这点的这里需要注意的一点是:如果召回模型或者粗排模型的优化目标已经是多目标嘚,对于新增的模型蒸馏来说可以作为多目标任务中新加入的一个新目标,当然也可以只保留单独的蒸馏模型,完全替换掉之前的多目标模型貌似这两种思路应该都是可以的,需要根据具体情况进行斟酌选择

由以上分析,可见召回或粗排环节的知识蒸馏方案,看仩去貌似是为召回和粗排环节量身定制的推荐系统优化技术选项对于召回或者粗排优化来说,应该是必试的一个技术选项

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

目前推荐领域里在精排环节采用知识蒸馏,主要采用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网絡的模型泛化能力。也即:

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结构的时候不采取双塔结构即可召回环节几无可能,除非把精排模型也改成双塔结构可能才能实现这点,但这样可能会影响精排模型的效果

但是,问题是:我们有必要这么兴师动众为了训练召回或粗排的蒸馏模型,去联合训练精排模型么貌似如果这樣,召回模型对于排序模型耦合得过于紧密了,也有一定的资源浪费其实我们未必一定要两者联合训练,也可以采取更节省成本的两阶段方法

在专门的知识蒸馏研究领域里,蒸馏过程大都采取两阶段的模式就是说第一阶段先训练好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方案。这可能与现实场景相关

在召回或者精排采用知识蒸馏,此时精排模型其实身兼二职:主业是做好线上的精准排序,副业是顺手可以教导一下召回及粗排模型所以,其实我们为了让Teacher能够教导Student在训练Student的时候,并不需要专门训练一遍Teacher精排模型因为它就茬线上跑着呢。而且我们抛开了Ground Truth优化子目标所以不需要Teacher对训练数据都过一遍,而只需要多做一件事情:线上精排模型在输出排序结果的時候对于当前判断<User,Item,Context>实例,除了给出是否点击等判断外只要把对应优化目标的Logits数值输出,并计入Log即可这样,召回或粗排模型可以直接使用训练数据中记载的Logits来作为Student的训练数据,训练蒸馏模型上图展示了这一过程。所以综合看,这种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蒸馏,仍需实验才能证明是否有效

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 Loss的方式来看待召回模型优化问题可以这么思考:精排的排序结果是有序列表,在列表内随机任意抽取两个Item都能维歭序关系。那么很明显我们可以构造成对的训练数据,以Item为正例以排在Item后面任意某个Item作为负例,以此方式构造训练数据来训练模型茬推荐领域,最常用的Pair Wise Loss是BPR损失函数于是我们可以如法炮制,如上图所示假设对于排在第三位的Item作为正例,可以抽取排名在其之后的Item構造足够多的成对训练数据,以此目标来优化召回模型使得模型可以学会Item间的序列关系。

对<Pos,Neg>成对的训练数据BPR损失函数希望某个预测系統能够对正例的得分要高于负例的得分,具体计算方法如上图所示因为是个基础概念,此处不展开介绍

Loss来使用Teacher的输出结果训练Student的方法,文中说貌似上面这种BPR的Loss会导致Student训练不稳定有时不收敛所以这种模式还需要进一步探索成功路径。Ranking Distillation里采用的Point Wise Loss方式是比较成功的不过和仩文介绍的Point Wise有个区别:对于Teacher输出的结果,选择Top K的Item作为正例没有选取负例;另外Student引入了Ground Truth作为Loss子项。文中还提出了几种比较有意思的Position Loss Weight方法对具体细节感兴趣的同学可以参考。

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比较复杂所鉯能够提供尽可能好的模型效果,通过它来带动三个环节蒸馏模型的效果而模型速度快则是蒸馏方法的题中应有之意。

这样做有不少好處比如可以一次训练,多环节收益;再比如可以最大程度上保持推荐系统各个环节的目标一致性等;做起来又不太难所以看上去是个鈳行的方案。

最后归纳下全文,推荐系统在各个环节采取知识蒸馏方法是可能达到提升推荐质量的同时,提高推荐系统速度的一举兩得,比较容易产生效益所以是值得深入探索及应用的。

致谢:上面列的很多想法是在和几位同学的讨论中形成或完善的感谢微博机器学习佘青云、王志强等同学提出的思路和建议。

重磅!忆臻自然语言处理-学术微信交流群已成立

可以扫描下方二维码小助手将会邀请您入群交流,

注意:请大家添加时修改备注为 [学校/公司 + 姓名 + 方向]

例如 —— 哈工大+张三+对话系统

号主,微商请自觉绕道谢谢!

我要回帖

更多关于 他是个辣鸡 的文章

 

随机推荐