推荐算法线上Serving

推荐系统的实时性

实验结果显示,模型更新越慢,效果就越差;

 

一. 推荐系统「 特征」的实时性:推荐系统的更新速度越快,越能够反应用户最近的用户习惯,越能够给用户进行越有时效性的推荐。

系统“实时”地收集推荐系统模型所需的输入特征,使推荐系统能够总是使用最新的特征进行预测和推荐。

1. 客户端实时性(无延迟):如果客户端能够缓存session内部的行为,作为与上下文特征同样的实时特征传给推荐服务器,那么推荐模型就能够实时得到session内部行为特征,进行实时的推荐。

2. 近线流式计算准实时性(分钟级别的延迟:storm,spark streaming,flink等;计算该时间窗口内的特征,例如:一个物品在该时间窗口内的曝光次数,点击次数,一个用户在该时间窗口内的点击话题分布等。

3. 离线训练(小时级的延迟):HDFS+Spark; 多个数据源的数据join,延迟信号的合并。

比如用户的曝光、点击、转化数据往往是在不同时间到达HDFS的,有些游戏类应用的转化数据的延迟甚至高达几个小时,因此也只有在这一阶段才能够进行全量特征以及相应label的抽取和合并。也只有在全量特征准备好之后,才能够进行更高阶的特征组合的工作。这往往是无法在客户端和流处理平台平台上进行的。


 

二. 推荐系统「 模型」的实时性:推荐系统更新的越快,模型更容易发现最新流行的数据pattern,越能够让模型反应找到最新的流行趋势。

特征实时性再强,影响的范围也仅限于当前用户,要想快速抓住系统级别的全局的数据变化和新产生的数据pattern,就必须加强“模型”的实时性。

举例来说: 拿某电商网站双十一的大量促销活动来说。特征的实时性会根据用户最近的行为更快的发现用户可能感兴趣的商品,但绝对不会发现用户相似人群最新的偏好,商品之间最新的相关性信息,新活动的趋势信息等。

1. 模型训练全量更新(天级延迟):spark+tensorflow;

2. 模型训练增量更新(小时延迟):

由于仅利用增量样本进行学习,因此模型在多个epoch之后也是收敛到新样本的最优点,而很难收敛到"原所有样本+增量样本"的全局最优点

因此在实际的推荐系统中,往往采用增量更新与全局更新相结合的方式,在进行几轮增量更新后,在业务量较小的时间窗口进行全局更新,纠正模型在增量更新过程后中积累的误差。在“实时性”和“全局最优”中间进行取舍和权衡。

3. 模型训练实时更新(秒延迟):

在线学习是在每次获得一个新样本的时候就实时更新模型。如果使用general的SGD方法,在线学习会导致一个很严重的问题,就是模型的稀疏性很差,打开过多“碎片化”的不重要特征。(微软的RDA,google的FOBOS和最著名的FTRL等,都是为了解决线上学习稀疏化的问题)

A. 模型的局部更新:

Facebook的GBDT+LR:GBDT更新慢;所以Facebook的线上部署是:每天训练一次GBDT模型,固定GBDT模型后,准实时的训练LR模型以快速捕捉数据整体的变化。

Embedding层+神经网络:Embedding层一层的参数往往占深度学习模型90%以上。因此Embedding层的更新会拖累模型整体的更新速度,因此业界也往往采用embedding层单独训练甚至预训练,embedding层以上的模型部分高频更新的策略。

B. 客户端模型的实时更新:

用户embedding的实时更新:对于物品embedding的更新来说,往往需要全局的数据,因此只能在服务器端进行整体的更新;而对用户embedding来说,则更多依赖于用户自身的数据。那么把用户embedding的更新过程移植到客户端来做,就能够实时地把用户最近的行为数据反应到用户的embedding中来,从而通过实时改变用户embedding的方式完成实时推荐。

例如:把用户最近点击过的item的embedding求avg-pooling/max-pooling(或者通过一个简单的网络),实时得到user-embedding。

 

三. 线上实时平台

1. 自研:上线FTRL的过程就是从参数服务器或内存数据库(不需要更新参数,所以用Redis就够了;如果要更新参数,用Redis就会造成两台机器上同时要更新的w有一台被忽略了,而用ps-lite可以让两台的g都顺序加到w上)中得到模型参数,然后用Java实现模型inference的逻辑。

2. 现在业界的很多公司其实采用了“复杂网络离线训练,生成embedding存入内存数据库,线上实现LR或浅层NN等轻量级模型拟合优化目标”的上线方式。

百度双塔模型:分别用复杂网络对“用户特征”和“广告特征”进行了embedding化,在最后的交叉层之前,用户特征和广告特征之间没有任何交互,这就形成了两个独立的“塔”,因此称为双塔模型。(有点儿像DSSM的Query和Doc都是一样的经过网络)。

在完成双塔模型的训练后,可以把最终的用户embedding和广告embedding存入内存数据库,在线上inference时,只需要实现最后一层的逻辑,在从内存数据库中取出用户embedding和广告embedding之后,通过简单计算即可得到最终的预估结果。(类似facebook的“召回”阶段,把video的embedding们全存下来了,user的embedding一到直接KNN查找)

用户侧塔的embedding通常是要经过网络得到的:用户侧塔的原始特征通常比较动态,一个是通常包含context特征,比如请求时间、当前地理位置之类的,这些都是没法离线准备好embedding的;二是对新用户embedding没办法离线提前准备好

3. PMML:“预测模型标记语言”,作为中间媒介连接离线训练平台和线上预测平台。

4. Tensorflow Serving及其改造:

利用TensorFlow自带的模型序列化函数可将训练好的模型参数和结构保存至某文件路径。

涉及到模型更新,整个docker container集群的维护和按需扩展等一系例工程问题;此外,TensorFlow Serving的性能问题也仍被业界诟病。

定制案例:A. 砍掉了传输,砍掉了数据打包再拆开的环节(序列化和反序列化),砍掉了一些为了通用但实际对我们大多数互联网业务没用的步骤;B. session run外面包了一层自研的server,比grpc更可控,性能调优还是更多的在模型本身。C.两种思路,一是把模型分裂成embedding和nn网络,弊端就是分裂模型了,不方便;另一种思路就是把TF里的PS(parameter-server?)给改造线上可用,这种思路优点很明显,更通用易扩展,但缺陷就是改造难度不好估量,不知是否行得通

 

 

最常见的实时性,除了排序的特征实时性和召回实时性外。通常,从产品角度会有个强插逻辑(强制召回下发最近一个正反馈相似资源

模型的实时性可以参考阿里妈妈(书里有)最近做的强化学习模型,采用markov模型,可以实现千pv千面

Facebook在2016年的client-side模型

广告确实和推荐场景完全不同,用户点击了某个广告也不能说明他非常喜欢看这类广告,从动机上来说,广告的行为就是完全不同的。

"知乎和抖音这种体验,在信息流里都是基本操作。实现这个大概需要几点:1、用户行为反馈实时回传;2、根据用户实时行为有特定的实时召回源,比如同上次点击/本session内所有点击平均相似度最接近的N个内容;3、保证实时召回源的内容可以排出去(如果有价值的话),这里需要通过rank模型相关特征保障:如果有召回源相关特征(match类特征)基本上已经可以做到,也就是如果实时召回的内容真的有价值,那么这个召回源召回的内容在排序时权重自然高,体现在该召回源的match类特征上。另外还可以试试跟abb那样,增加每个待排序内容同用户近期点击的内容、近期没点击内容的相似度特征,abb的实践看这两个特征也很强"

"知乎 timeline 对用户行为反馈的实时性主要通过如下方式实现:1)kafka + spark streaming 收集用户 last-n 行为(延时大概是 2 分钟以内,大部分是 1 分钟);2)采用 last-n + itemcf 的方式召回与用户最近阅读行为相似的内容。没有做特别的 rerank 提权策略,主要还是 ranking 模型能够学习到召回的内容与 item 之间的 match 信息(last-n 同时更新了用户的实时兴趣,是 ranking 模型的特征)。"

模型实时性很重要:特别是样本分布变化大的场景,例如大促(大促,大促前夕,春节情人节等某些节假日用户行为发生重大变化时,在线学习可以更快的抓住全局层面的新的数据模式。其实每天的不同时段商品的ctr也不同,模型训练的过程可以看成是在拟合这个ctr的过程。如果样本量够大,把hour作为特征,理论上也能拟合不同时段的ctr。

正样本的延迟问题:在商品cvr的学习中特别明显(还有游戏内购买类的曝光转化延迟)。比如我们将窗口设为1小时,那么1小时后的成交正样本可能就被丢弃了,同时还导致模型之前学习到了假的负样本。建议是以更大的weight回刷这个正样本(做错误转化信号的补偿性重新练)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章