本系列文章包含每平每屋过去一年在召回、排序和冷启动等模块中的一些探索和实践经验,本文为该专题的第三篇。

第一篇指路:冷启动系统优化与内容潜力预估实践

第二篇指路:GNN在轻应用内容推荐中的召回实践

前言背景

淘宝内的每平每屋频道是每平每屋业务获取C端流量并进行内容分发从而建立用户家居、生活方式心智场的主要阵地。在每平每屋频道中,内容主要以场景搭配为主,内容内挂载了多个商品锚点,点击商品锚点可以跳转到商品的详情页。

一直以来,我们结合业务特点利用算法技术提升用户浏览体验、流量分发效率和整体的系统生态。其中排序环节的迭代优化对于提升系统的分发效率至关重要,如下图展示在模型结构和样本特征两方面我们进行了大量的尝试和优化工作,但在模型训练方式的升级上进展缓慢。

在电商搜推等用户行为和环境不断变化的场景中,在线学习能够显著提高模型对于线上流量分布变化响应速度,但整个流程相比于离线学习会复杂很多,这其中包括实时曝光点击数据的收集,实时特征采集,流式样本生成,模型实时训练和更新等流程,这些流程环环相扣,既需要保证逻辑正确性还需要保证时效性。

在20年底我们曾探索过模型的实时在线学习,由于当时对Porsche和AOP等流式训练平台和组件的了解还不充分,只是初步走通了ODL模型训练的链路,并未在线上取得收益。在21年通过调研发现AMC特征中心的特征全埋点功能和porsche开发团队打造PyPorsche可以极大的简化ODL链路中的实时特征采集和样本生成流程,所以决定对原数据链路进行改造,并基于新的数据链路进行精排模型的ODL训练。

本文将从流式样本生成模型实时训练两大块介绍每平每屋轻应用ODL链路搭建的实践经验,其中涉及到的AMC特征中心、PyPorsche、AOP和xDeepCTR等平台框架的使用方法请参考对应的文档,不再赘述。

流式样本生成

  数据流架构

在每平每屋频道中,流式样本生成环节主要涉及到了:

  1. UT行为日志解析

  2. 全埋点特征解析

  3. ODL 训练样本生成

  UT行为日志解析

首先根据event_id,args,arg1以及trackkey,trackinfo等字段从UT日志流中过滤出业务所需的曝光和点击日志,并按一定格式写入TT用于在PyPorsche构建event。

以下是解析得到曝光日志并写入TT流的Blink代码片段,table中的字段可以根据实际需要更改:

create table r_ihome_lapp_content_expo
(pvid                VARCHAR,user_id             VARCHAR,item_id             VARCHAR,server_timestamp    VARCHAR
) with (type='tt',topic='dwd_ihome_lapp_content_expo_sample',accessKey=''
);INSERT INTO r_ihome_lapp_content_expo
select * FROM XXX WHERE YYY;

  特征全埋点

在上一环节可以获取到业务场景内产生的曝光TT流和点击TT流,但ODL模型的训练除了需要userid,itemid,label等基本信息外,还需要对应user侧,item侧以及context侧特征。利用AMC特征中心的特征全埋点功能可以对线上参与打分的现场特征进行完整记录并落盘到TT中。

  ODL 训练样本生成

上述两个环节完成后可以得到业务内的曝光点击以及全埋点特征TT流,接下来还需要将这些流数据按一定的规则进行关联,并产生最终可供ODL模型训练使用的流样本。

PyPorsche将ODL样本构建拆分为3个主要流程,分别为:

1. event流程构建

2. 流式样本骨架构建

3. ODL swift 样本构建

每一个流程环节只需要编写若干行Python代码即可完成开发。

  • event流程构建

首先对曝光/点击和全埋点特征TT流进行日志解析生成对应的event,在 PyPorsche 中,实时特征被称为 Event。

每个event表具有自己的schema和主键,注意event_ids为业务的唯一主键,index_fields中需填入后续会用于和其他表进行join操作的字段。

以下是将曝光的TT流解析并转换为对应event的代码片段:

tt_source = TTSource(TT(topic='dwd_ihome_lapp_content_expo_sample',access_id='',access_key=''),parser_clazz='com.alibaba.pyporsche.ihome.IhomeLappLogParser',schema=ihome_tt_schema)#schema
tt_source = session.register_table(tt_source)ihomelapp_sink = session.register_table(EventSink(Event(event_name=EVENT_NAME_EXPO, event_ids=['pv_id', 'item_id'],index_fields=['pv_id', 'user_id', 'item_id'])))
tt_source.insert(ihomelapp_sink)

在上面的片段中,曝光event具有5个字段,其中pv_id,item_id,user_id,record_timestamp 这4个属性是通过ihome_tt_schema定义得到,而event_id是通过event_ids指定根据pv_id和item_id拼接得到。表的schema如下:

注意,由于xDeepCTR 3.0中将label放置在了features字段中,需要在xfc_event构建时将label特征从fg.json中移除,否则可能会导致最终产出的流式样本label为空

  • 流式样本骨架构建

在backbone的构建中,需指定一个主event,并从主event出发关联起若干event。在每平每屋场景中,曝光event被作为主event并以keyed_join的形式关联起一跳点击event和详情页的二跳点击event以及对应的全埋点特征event。

以下是将曝光event,一跳点击和二跳点击以及全埋点特征event进行关联并产生backbone的代码片段:

pv_event = session.get_table('event.' + EVENT_NAME_EXPO) # 主event
full_tracking_event = session.get_table('event.' + EVENT_NAME_FULL_TRACK)
click_event = session.get_table('event.' + EVENT_NAME_CLICK)
detail_click_event = session.get_table('event.' + EVENT_NAME_DETAIL_CLICK)wide_table = pv_event.keyed_join(click_event, condition='pv_id=pv_id,item_id=item_id',join_type='ONE_TO_MANY', left_wait_second=630,tps=100)
wide_table = wide_table.keyed_join(detail_click_event, condition='pv_id=pv_id,item_id=item_id',join_type='ONE_TO_MANY', left_wait_second=1,tps=100)output_table = wide_table.keyed_join(full_tracking_event, 'pv_id=pv_id,item_id=item_id', join_type='ONE_TO_ONE',left_wait_second=-630,tps=3000)output_table.insert(session.register_table(BackboneSink(Backbone(BACKBONE_NAME))))

通过prosche任务页面的监控可以看到在当前等待时间下各event中数据被join上的的比例,pos表示join上的记录,neg表示没有被join上的记录,根据丢弃比例可以调整等待时间left_wait_second

  • ODL swift 样本构建

ODL模型训练样本构建环节需要将backbone中的相关字段进行提取并转化为模型训练要求的格式。另外,为了方便复用原来的批模型(基于xDeepCTR的单source多label形式),我们采取的是在单数据源中包含多目标样本的方式,所以还需要在这个环节将多个目标的label字段拼接到features字段中,使得模型能够识别。

在最后的sink环节定义的swift name就是ODL模型训练任务中数据源的swift_topic。为了便于验证样本的正确性,可以将一定比例的样本写入TT回流到ODPS中进行离线数据分析。

下面是对backbone进行LG并产生swift样本的代码片段:

backbone = session.get_table(BACKBONE_NAME)
# lg
wide_table = backbone.select('*, event_'+EVENT_NAME_FULL_TRACK+'_features as features')
wide_table = wide_table.join_lateral(Lg('*', lgClass='com.alibaba.pyporsche.ihome.IhomeLappClickLG'))
wide_table = wide_table.filter("features IS NOT NULL")
wide_table = wide_table.with_column(AddLabelToFeatures('features,label', label_name="click_label").as_('features'))# fg
wide_table = wide_table.select('event_id as uniqueId, features, label, type')# sink tt
tt_sink = TTSink(TT(topic='ihome_lapp_rank_sample_tt', access_key=''),line_separator='\n', field_separator='\t')
tt_sink = session.register_table(tt_sink)
wide_table.filter('rand() < 0.1').insert(tt_sink)# swift sink
swift_sink = session.register_table(SwiftSink(Swift('ihome_lapp_rank_sample_event')))
wide_table.insert(swift_sink)

  样本质量监控

AMC算法质量监控中心提供了流样本的监控功能,在这里可以观测到样本的产出延迟,消费延迟和样本比例以及特征的取值统计等信息。

模型实时训练

模型的训练环节使用xDeepCTR框架在AOP平台上进行。

对比使用批样本训练模型,使用流样本训练模型在配置文件上需要做以下两处改动:

  1. 在主入口类文件main_op_aop.py中指定ODL模型从哪个全量训练的模型版本进行参数初始化

  2. 在训练配置user_params.json中指定使用流样本数据源,并配置实时参数推送的hook

下面以xDeepCTR中内置的MMOE模型为例说明从离线学习切换为在线学习的主要改动:

  模型参数初始化

实时训练的模型数据源为swift样本,在入口文件中将source配置为空串即可,AOP会加载user_params.json中指定的数据源进行训练。

通过train_from_modeltrain_from_version参数可以指定ODL模型初始化时的参数来自于哪个模型和对应的版本。

from aop import odps_table, tf_train, AOPClient
if __name__ == '__main__':fg_path = './ihome_rank_model_fg.json'user_params_path = "./user_params.json"algo_conf_path = './algo_conf.json'running_config_path = "./running_config.json"repo_name = 'xDeepCTR'zip_name = './' + repo_name + '.zip'model_path = repo_name + '/xdeepctr/models/multitask/mmoe.py'model_name = "ihome_rank_demo_mmoe_odl"ACCESS_ID = 'XXXX'ACCESS_KEY = 'YYYY'source = ""#source为空串即可train = tf_train(source,fg_config=fg_path,model_path=model_path,model_name=model_name,user_params=user_params_path,train_from_model='ihome_rank_demo_mmoe',#使用ihome_rank_demo_mmoe模型的最新版本来初始化train_from_version='NEWEST',  # NEW NEWESTps_num=2,worker_num=3,)with AOPClient(model_name) as client:client.add_code(zip_name)client.add_resource(algo_conf_path)client.add_debug_version("aop_version_tf112")client.add_runconf(running_config_path)client.run(train)

  实时数据源和参数更新

需要user_params.json修改数据源配置,并添加一个发送参数至RTP的hook。相比于批模型的训练方式read_modeodps_single变更为了swift_single,含义为从一份swift 样本中读取训练数据,若为多份样本可以使用swift

source配置中,swift_topic为PyPorsche的ODL样本生成节点中配置的swift名称,通常sample_nameswift_topic保持一致即可。

最后需要在customized_functions中添加一个odl_model_updatehook,我们使用PS直发的方式将实时训练的模型参数定期发送至RTP,其中dense参数以5分钟的间隔发送,sparse参数以15分钟的间隔发送。除了添加hook外,还需要在代码中打开optimizer 的open_auto_record开关,并对RTP进行设置调整,详细步骤可参阅AOP和RTP相关文档。

下面是一个ODL模型的配置例子:

"customized_functions": {"odl_model_update": {"open": true,"is_sync": true,"rtp_table_name": "ihome_rank_demo_mmoe_odl","rtp_table_topic": "ihome_rank_demo_mmoe_odl_swift_${today}","swift_partition_count": 32,"swift_partition_max_buffer_size": 5120,"reuse_topic" : false,"interval_time": 300,"dense_send_interval_time": 300,"sparse_send_interval_time": 900,"first_trigger_time": 600,"global_auc_threshold": "0.68","current_auc_threshold": "0.68","part_strategy": "div","check_numerics": false}
}

  流程调度

在实验阶段以7天为周期对ODL模型进行重新加载批模型参数初始化和在线学习。一个完整的ODL任务涉及到了

  1. 批模型训练并产出模型版本

  2. ODL模型从批模型加载参数初始化并创建新版本

  3. ODL模型新版本和参数更新的topic配置推送到rtp,等待RTP进行模型索引构建和切换

  4. ODL训练任务启动,定期推送更新的参数至RTP

整个流程涉及到了不同任务的调度和对RTP索引构建和业务切换状态的监控,AOP pipeline对上述业务逻辑进行了抽象并提供了一套api供算法同学串联起全流程并定期调度。

  在线参数生效监控

当一切流程正常运行后,可以通过AOP-模型管理中的增量版本菜单查看线上参数是否生效以及生效的时间。

参数更新的状态包括3种:

  1. FINISHED:已发送且确认上线完成,该状态下会产出生效时间

  2. PUSH_ONLINE:已发送待确认

  3. SWITCH_TIMEOUT:超过6个小时没切换完成

注意如果修改过odl_model_updateemb_size_thd可能导致该功能无法正常产生结果。这是因为模型部署时RTP会按一定规则产生sparse和dense两种索引,修改该参数会导致对一些变量检测时查了另外的索引,从而无法获取的对应变量的更新状态。

业务效果

在淘宝每平每屋频道首页推荐tab场景中,我们分别在日常和大促期间进行了线上AB实验,结果表明ODL模型相较于天级更新的模型具有明显的效果提升。在日常期间CTR+7.83%/人均曝光+2.15%/人均点击+10.15%/人均详情页点击+9.56%。在双11当天ODL模型在浏览深度和二跳转化目标的提升上更加显著,CTR+7.04%/人均曝光+3.94%/人均点击+11.26%/人均详情页点击+13.03%,说明ODL模型在流量分布发生剧烈变化的情况下的快速适应能力。

ODL流样本中使用到了全埋点特征,我们在离线批模型中单独验证了全埋点特征的收益,在日常期间CTR+6.83%/人均曝光+0.82%/人均点击+7.70%/人均详情页点击+7.11%,ODL在此基础上进一步提升了人均浏览篇数和点击效率。

总结

实时化对于推荐系统捕捉用户的兴趣和流量分布变化非常关键,本文介绍了每平每屋频道精排模型向ODL升级的实践总结,深度模型的在线学习对整个系统具有极大的挑战,充分利用集团内部的平台和工具可以大幅缩短ODL链路搭建所需的时间,推动在线学习的落地并取得收益。

未来我们会在模型的在线学习方面进行持续的迭代和优化,包括将其扩展至重排/粗排以及冷启动等环节,探索流式训练场景下的数据Non-IID问题/label延迟问题以及参数更新梯度衰减等问题,并进一步提升实时链路的稳定性和正确性,以期获得更大的业务效果。

团队介绍

大淘宝技术-淘宝智能团队

淘宝智能团队是一支数据和算法一体的团队,服务于淘宝、天猫、聚划算、闲鱼和每平每屋等业务线的二十余个业务场景,提供线上零售、内容社区、3D智能设计和端上智能等数据和算法服务。我们通过机器学习、强化学习、数据挖掘、机器视觉、NLP、运筹学、3D算法、搜索和推荐算法,为千万商家寻找商机,为平台运营提供智能化方案,为用户提高使用体验,为设计师提供自动搭配和布局,从而促进平台和生态的供给繁荣和用户增长,不断拓展商业边界。

这是一支快速成长中的学习型团队。在创造业务价值的同时,我们不断输出学术成果,在KDD、ICCV、Management Science等国际会议和杂志上发表数篇学术论文。团队学习氛围浓厚,每年组织上百场技术分享交流,互相学习和启发。真诚邀请海内外相关方向的优秀人才加入我们,在这里成长并贡献才智。

如果您有兴趣可将简历发至weichen.swc@alibaba-inc.com,期待您的加入!

✿  拓展阅读

作者|阅谦

编辑|橙子君

出品|阿里巴巴新零售淘系技术

基于特征全埋点的精排ODL实践总结相关推荐

  1. 京东推荐算法精排技术实践

    猜你喜欢 0.2021年轻人性生活调研报告1.如何搭建一套个性化推荐系统?2.从零开始搭建创业公司后台技术栈3.2021年9月份热门报告免费下载4.微博推荐算法实践与机器学习平台演进5.腾讯PCG推荐 ...

  2. 业界分享 | 京东推荐算法精排技术实践

    作者 | 王冬月 京东 京东主站推荐的主要业务场景覆盖APP中用户购买前.购买中和购买后的全流程,日均千万级DAU.不同业务场景下用户需求不同,我们相应的优化目标也不同. 首页feeds和" ...

  3. 电商场景中的精排服务实践

    一.精排服务框架 推荐系统架构中,包括推荐引擎.召回服务.频控服务.粗排服务.排序服务.机制服务. 框架流程图: 机器学习平台: 参数服务器: 二.DNN/DeepFM排序模型 DNN模型 DeepF ...

  4. 直播推荐、搜索中的召回、相关性、多目标精排、特征、重排 - 多目标精排(3) - loss权重的4种方案

    一.多目标学习在推荐系统的应用(MMOE/ESMM/PLE) - 知乎 这篇文章中主要针对回归任务.分类任务两种目标来对不同任务设置不同的参数.博主主要记录下里面的公式推导部分和这样做的原因 (1) ...

  5. 知识蒸馏在推荐精排中的应用与实践

    作者 | Chilia 哥伦比亚大学 nlp搜索推荐 整理 | NewBeeNLP 知识蒸馏主要分为两类:logits蒸馏和中间特征蒸馏.其中,logits蒸馏指的是在softmax时使用较高的温度系 ...

  6. 一文看懂推荐系统:概要02:推荐系统的链路,从召回粗排,到精排,到重排,最终推荐展示给用户

    一文看懂推荐系统:概要02:推荐系统的链路,从召回粗排,到精排,到重排,最终推荐展示给用户 提示:最近系统性地学习推荐系统的课程.我们以小红书的场景为例,讲工业界的推荐系统. 我只讲工业界实际有用的技 ...

  7. 自动售货机 顺序图_基于自动售货机的软件工程(精)

    基于自动售货机的软件工程(精) 面向对象分析实践大作业(40% 下面是自动售货机系统的需求陈述,请你: 1. 编写分析和设计报告; 2. 报告分需求分析.系统设计和对象设计三部分编撰, 各部分应按相应 ...

  8. 全链路总结!推荐算法召回-粗排-精排

    作者 | Salon sai  整理 | NewBeeNLP https://zhuanlan.zhihu.com/p/463021052 大家好,这里是NewBeeNLP.现在的推荐系统都是一个很大 ...

  9. LIVE 预告 | 快手宋洋:千亿特征,万亿参数,快手推荐精排模型的发展史

    随着GPT-3给人们带来的震撼,大模型在各个应用领域得到迅速的发展和应用. 近期,媒体平台「机器之心」上发布了一篇文章「1.9万亿参数量,快手落地业界首个万亿参数推荐精排模型」,其中提到快手开发的精排 ...

  10. 【推荐系统】关于精排的特征

    精排特征 精排能够利用的特征是最丰富的,需要分为三大类 user类:用户长短期画像.点击/收藏/购买历史.......等 item类:物料画像.物料的后验指标(e.g., CTR.时长)....... ...

最新文章

  1. 我的世界服务器老是显示已断开,为什么我的服务器玩家老是掉线 - 有问必答 - 最MC论坛 - 我的世界_Minecraft_联机_服主_资讯_MOD_皮肤_交流_作品_中文论坛...
  2. mac mysql 可视化工具_推荐3款好用的Redis、MySQL和MongoDB可视化管理工具
  3. TCP 、UDP各自的优缺点
  4. Hadoop 2.2.0 集群搭建
  5. 【NLP】如何系统性的学习NLP,有三AI-NLP知识星球等你来
  6. sscanf,sprintf,fscanf,fprintf 系列函数
  7. SparkSQL之External Data
  8. oracle元数据存储在表空间,oracle db中数据和元数据的概念
  9. 使用jenkins进行项目的自动构建部署
  10. mysql 1005 - can't create table_关于创建数据表报错一例(ERROR 1005 Can’t create table (errno: 121))...
  11. Qt5.7+Opencv2.4.9人脸识别(四)模型训练
  12. 深入解读 Entity Framework 4.0和4.1
  13. 基金学习20190802
  14. java nio web,JavaWeb之三——网络IO和NIO
  15. jQuery实现滑动门效果
  16. P6647 [CCC 2019] Tourism
  17. 我读《非暴力沟通》- 马歇尔 *卢森堡 - 让爱融入生活
  18. 猴子选大王(python)
  19. Java中hir_Java中数据库的使用基础
  20. java response excel_java-返回在servlet中创建的excel文件作为响应

热门文章

  1. html在表格输入文字不显示,Word表格中有部分格子内无法输入文字是怎么回事?...
  2. Gym100015 I Identity Checker 栈容器使用,数学
  3. xxl-job的学习使用
  4. win10 下装win7
  5. nodejs实现读取本地目录生成文件树
  6. 目标检测经典论文详解
  7. 跑三小时的monkey测试该怎么算_Android命令Monkey压力测试,详解
  8. KernelBase.dll中有未经处理的异常,求助大神!!!
  9. Error: The project seems to require yarn but it‘s not installed.
  10. 红罐王老吉品牌定位战略