1. 背景
随着互联网的疾速倒退,互联网上呈现了各种海量的信息。怎么样为用户举荐感兴趣的信息是个很大的挑战?各种各样的举荐算法、零碎都涌现进去。而预估引擎能够说是举荐零碎中比拟重要的一环,预估引擎成果的好坏重大影响了算法成果。联合oppo的业务场景,咱们的预估引擎须要解决几个问题:
(1)通用性:oppo的举荐业务场景十分多,包含信息流、商店、短视频、联盟、锁屏杂志、音乐等业务,预估引擎要反对这么多的场景,框架肯定要通用。
(2)多模型预估:在广告场景中,须要反对ocpx,须要一次申请同时预估ctr和cvr,可能是多个不同的转化模型(例如下载、付费等)。
(3)模型的动静更新:有些模型是小时更新、有些模型是天级更新,须要做到可能无感的动静更新。
(4)扩展性:各个业务用到的特色、字典、模型类型都可能不一样,要做到比拟容易扩大。
2. 定位与技术选型
思考到各个业务的业务特色差别比拟大,对立预估引擎如果要反对各个业务的策略试验和分流试验,会让预估引擎模块十分臃肿,没法保护。所以最终决定预估引擎只做预估相干的事件。
从原始数据到失去预估ctr后果,须要通过特征提取,提取特色之后的后果再进行模型预估。思考到特征提取后果比拟大,一次预估须要用的特色后果大概有2M,这么大的数据如果通过网络来传输,耗时太长。所以预估引擎总体的流程包含了两局部:特征提取和模型预估。
3. Predictor的设计与实现
3.1 Predictor模块在整个举荐零碎中的地位
以oppo手机利用市场为类来阐明predictor模块在整个零碎中的地位, ranker模块负责排序,包含各种分流试验和各种经营策略等。它通过grpc框架与predictor模块进行通信。
3.2 Predictor模块的主体流程
图中示意了两个申请的解决流程,图中提特色包含多个特色conf,每个样本、每个特色配置提取一次。预估也会是多个模型,每个样本、每个conf、每个模型会预估屡次。特征提取依赖内部字典,预估依赖内部的模型文件,内部字典的更新、双buf切换都是通过字典治理模块来实现的。上面别离就字典治理模块、分task, 提特色,预估,merge进行具体阐明。
3.3 字典治理模块
如下图所示:conf1, conf2, lr_model_x0等示意磁盘上的文件,每个文件名都是通过不同的字典解析类来解析,这个字典解析类负责管理这个文件的加载,双buf切换。例如:FeatureConfDict负责解析conf1,它外部保留两个FeatureConfList类型的buf,当conf1文件产生更新时,就用备的FeatureConfList 进行加载,加载实现后,在加载过程中,服务应用主的FeatureConfList指针。加载实现后,进行主从切换,待没有申请应用老的buf,就开释到老的buf内存。
3.4 分task逻辑
接管到一个申请,这个申请指定了多conf多模型来预估。如下图所示:
上图示意一共有8条样本,别离用两个conf:conf0, conf1来提取特色,其中conf0的后果由model0,model1来预估,conf1由model2,model3来预估。依照2个样本一个task,拆分完task之后会失去4个task,如下图所示:
依照样本维度进行拆分成4个task,丢到线程池去执行。
3.5 Merge流程
在预估实现之后,须要依照conf/model这个维度进行组织预估后果给ranker, 最终的response如下图右子图所示。
3.6 特征提取框架的设计
特征提取框架线上、线下都会用到,这样比拟好保障线上线下的一致性。所以设计的时候要同时思考到线上线下的业务场景。
线上是将申请带来的数据与字典数据拼成一条条样本,进行特征提取的。而线下是编译so,通过mapreduce来调用,样本是通过反序列化hdfs的一条条文本失去的。
3.6.1 特色配置文件格式
特色配置文件包含两局部: schema局部,特色算子局部。
3.6.2 schema局部
上图中有5个 schema配置
user_schema:示意以后的用户相干信息,只在在线形式应用,由上游申请带过去。
item_schema:示意举荐的item相干信息,只在在线形式应用,一部分由申请带过去,一部分由字典文件中获取。
context_schema:示意举荐的上下文相干信息,只在在线形式应用,由上游戏申请带过去。例如:以后网络状态是wifi还是4G。
all_schema: 示意最终的样本的schema信息。在线模式是将user_schema, item_schema,context_schema的各个字段放在all_schema的对应地位,离线模块是将hdfs的一行行文本,依照all_schema_type指定的类型进行反序列化生成的。不论是在线还是离线,特色框架的样本最终的字段程序都是依照all_schema程序寄存的
all_schema_type: 离线模式才会用到,指定了各个schema的类型,这些类型名都是当时定义好的,在离线模式下,依据schema类型来反序列化各个字段。
3.6.3 特色算子配置局部
每个特色包含上面这些字段:
Name: 特色名字
Class:示意这个特色用的哪个特色算子类,对应代码里类名
Slot: 惟一标识一个特色
Depend: 示意该特色依赖哪些字段, 这个字段在上述all_schema中必须存在
Args: 示意传给特色算子的参数, 框架会转成float传给算子
Str_args: 传给特色算子的参数,以字符串的模式传递。
3.6.4 特色分group(common和uncommon)
一次预估申请外面,所有样本的用户和context信息是一样的, 思考到有些特色只依赖用户和context信息,这部分特色只须要提取一次,所有样本共用。
特色配置外面一部分特色会依赖其余的特色(例如组合特色、 cvm特色),所以须要对特色的依赖进行剖析,用来判断一个特色最终依赖的字段信息。
i_id特色依赖item字段的item_id,所以它是uncommon特色
u_a/net特色只依赖user_schema或者context字段, 不依赖item字段,所以它是common特色
u_a-i_id组合特色依赖i_id特色,距离依赖item_id,所以它是uncommon特色,
u_a-net组合特色只依赖u_a和network字段,所以它是common特色,在特征提取的时候,一次申请只算一次。
留神:这里特色分group是异步字典更新线程来负责计算好的,不是申请来了现算的。
3.7 预估局部
后面提到了,一个申请外面指定了用哪个特色配置文件来提取特色,用哪个模型来预估。所有的模型都是有异步字典更新线程来负责更新。目前反对了LR, FM, DSSM, Deep&Wide等模型的预估,并且比拟容易扩大。上面大略介绍下两个依据业务场景做了深度优化的模型:
3.7.1 FM模型预估(LR相似)
其中
思考到业务场景,多个样本的user/context信息是一样的,那么线上FM的 预估能够写成这个模式:
标红局部所有样本都是一样的,一个申请只用计算一次。
3.7.2 DSSM(双塔)模型
双塔模型的网络结构如下图所示:
实际上一共有三个塔,C(context信息),U(user信息), I(item信息), user与item子塔失去的向量通过点积,再与C进行求和。
3.7.3 在线serving局部
思考一些场景的item的信息变动比较慢,个别离线将item的子塔先计算好,失去向量,通过字典的形式动静加载。
在线的时候只用计算c塔,u塔, 一个申请只有一条样本须要计算;I塔局部由查字典失去向量。计算量相比全连贯,大幅度缩小。性能有大幅度的晋升,然而因为user信息与item只有一层点积相乘,相比全连贯,离线auc会降落1%,所以比拟适宜召回或者粗排等对准确度要求不高的场景。在信息流广告、联盟广告业务替换原来的统计 ctr粗排,综合指标晋升5、6个百分点。
3.8 性能优化
预估引擎模块对时延要求很高,然而为了达到比拟好的算法成果,特色规模又在一直的减少,所以在设计预估引擎的时候,做了很多性能优化的考量。次要包含以下几个方面:
(1)通过对象池来缩小内存调配,进步性能。
(2) 特色字段的依赖都当时转化成下标,在提取特色的时候,就间接应用下标来取对应的字段,缩小计算量。
(3)有些特色依赖其余特色后果,会频繁依照slot去查问对应后果,思考到slot数据无限,采纳数组来代替。
4. 总结
目前predictor模块反对了大多数举荐场景,包含信息流内容、信息流广告、利用市场、联盟、搜寻、短视频、oppo锁屏杂志、音乐等场景,部署在近2000台机器上,阐明这套设计还比较稳定、扩展性比拟好。目前反对业务平滑的切换到dnn模型,各个业务场景都获得肯定的收益。
作者简介
肖超 高级数据挖掘工程师
10+年的广告系统工程落地教训,在oppo次要负责模型的特征提取、推理的工程落地工作。
更多精彩内容,请扫码关注【OPPO互联网技术】公众号
发表回复