GTLC全球技术领导力峰会·上海站,首批讲师正式上线! 了解详情
写点什么

推荐系统工程难题:如何做好深度学习 CTR 模型线上 Serving

2019 年 8 月 10 日

推荐系统工程难题:如何做好深度学习CTR模型线上Serving

本文是王喆在 AI 前线 开设的原创技术专栏“深度学习 CTR 预估模型实践”第七篇文章(以下“深度学习 CTR 预估模型实践”简称“深度 CTR 模型”)。回顾王喆老师过往精彩文章:《推荐系统工程师必看!Embedding 技术在深度学习 CTR 模型中的应用》《谷歌、阿里等 10 大深度学习 CTR 模型最全演化图谱》《重读 Youtube 深度学习推荐系统论文,字字珠玑,惊为神文》《YouTube 深度学习推荐系统的十大工程问题》


这篇文章希望讨论的问题是深度学习 CTR 模型的线上 serving 问题。对于 CTR 模型的离线训练,很多同学已经非常熟悉,无论是 TensorFlow,PyTorch,还是传统一点的 Spark MLlib 都提供了比较成熟的离线并行训练环境。但 CTR 模型终究是要在线上环境使用的,如何将离线训练好的模型部署于线上的生产环境,进行线上实时的 inference,其实一直是业界的一个难点。本篇文章希望跟大家讨论一下几种可行的 CTR 模型线上 serving 方法。


自研平台

无论是在五六年前深度学习刚兴起的时代,还是 TensorFlow,PyTorch 已经大行其道的今天,自研机器学习训练与上线的平台仍然是很多大中型公司的重要选项。为什么放着灵活且成熟的 TensorFlow 不用,而要从头到尾进行模型和平台自研呢?重要的原因是由于 TensorFlow 等通用平台为了灵活性和通用性支持大量冗余的功能,导致平台过重,难以修改和定制。而自研平台的好处是可以根据公司业务和需求进行定制化的实现,并兼顾模型 serving 的效率。笔者在之前的工作中就曾经参与过 FTRL 和 DNN 的实现和线上 serving 平台的开发。由于不依赖于任何第三方工具,线上 serving 过程可以根据生产环境进行实现,比如采用 Java Server 作为线上服务器,那么上线 FTRL 的过程就是从参数服务器或内存数据库中得到模型参数,然后用 Java 实现模型 inference 的逻辑。


但自研平台的弊端也是显而易见的,由于实现模型的时间成本较高,自研一到两种模型是可行的,但往往无法做到数十种模型的实现、比较、和调优。而在模型结构层出不穷的今天,自研模型的迭代周期过长。因此自研平台和模型往往只在大公司采用,或者在已经确定模型结构的前提下,手动实现 inference 过程的时候采用。


预训练 embedding+轻量级模型

完全采用自研模型存在工作量大和灵活性差的问题,在各类复杂模型演化迅速的今天,自研模型的弊端更加明显,那么有没有能够结合通用平台的灵活性、功能的多样性,和自研模型线上 inference 高效性的方法呢?答案是肯定的。


现在业界的很多公司其实采用了“复杂网络离线训练,生成 embedding 存入内存数据库,线上实现 LR 或浅层 NN 等轻量级模型拟合优化目标”的上线方式。百度曾经成功应用的“双塔”模型是非常典型的例子(如图 1)。



图 1 百度的“双塔”模型


百度的双塔模型分别用复杂网络对“用户特征”和“广告特征”进行了 embedding 化,在最后的交叉层之前,用户特征和广告特征之间没有任何交互,这就形成了两个独立的“塔”,因此称为双塔模型。


在完成双塔模型的训练后,可以把最终的用户 embedding 和广告 embedding 存入内存数据库。而在线上 inference 时,也不用复现复杂网络,只需要实现最后一层的逻辑,在从内存数据库中取出用户 embedding 和广告 embedding 之后,通过简单计算即可得到最终的预估结果。


同样,在 graph embedding 技术已经非常强大的今天,利用 embedding 离线训练的方法已经可以融入大量 user 和 item 信息。那么利用预训练的 embedding 就可以大大降低线上预估模型的复杂度,从而使得手动实现深度学习网络的 inference 逻辑成为可能。


PMML

Embedding+线上简单模型的方法是实用却高效的。但无论如何还是把模型进行了割裂。不完全是 End2End 训练+End2End 部署这种最“完美”的形式。有没有能够在离线训练完模型之后,直接部署模型的方式呢?本小节介绍一种脱离于平台的通用的模型部署方式 PMML。


PMML 的全称是“预测模型标记语言”(Predictive Model Markup Language, PMML)。是一种通用的以 XML 的形式表示不同模型结构参数的标记语言。在模型上线的过程中,PMML 经常作为中间媒介连接离线训练平台和线上预测平台。


这里以 Spark MLlib 模型的训练和上线过程为例解释 PMML 在整个机器学习模型训练及上线流程中扮演的角色(如图 2)。



图 2 Spark 模型利用 PMML 的上线过程


图 2 中的例子使用了 JPMML 作为序列化和解析 PMML 文件的 library。JPMML 项目分为 Spark 和 Java Server 两部分。Spark 部分的 library 完成 Spark MLlib 模型的序列化,生成 PMML 文件并保存到线上服务器能够触达的数据库或文件系统中;Java Server 部分则完成 PMML 模型的解析,并生成预估模型,完成和业务逻辑的整合。


由于 JPMML 在 Java Server 部分只进行 inference,不用考虑模型训练、分布式部署等一系列问题,因此 library 比较轻,能够高效的完成预估过程。与 JPMML 相似的开源项目还有 Mleap,同样采用了 PMML 作为模型转换和上线的媒介。


事实上,JPMML 和 MLeap 也具备 sk-learn,TensorFlow 简单模型的转换和上线能力。但针对 TensorFlow 的复杂模型,PMML 语言的表达能力是不够的,因此上线 TensorFlow 模型就需要 TensorFlow 的原生支持——TensorFlow Serving。


TensorFlow Serving

TensorFlow Serving 是 TensorFlow 推出的原生的模型 serving 服务器。本质上讲 TensorFlow Serving 的工作流程和 PMML 类的工具的流程是一致的。不同之处在于 TensorFlow 定义了自己的模型序列化标准。利用 TensorFlow 自带的模型序列化函数可将训练好的模型参数和结构保存至某文件路径。


TensorFlow Serving 最普遍也是最便捷的 serving 方式是使用 Docker 建立模型 Serving API。在准备好 Docker 环境后,仅需要 pull image 即可完成 TensorFlow Serving 环境的安装和准备:


docker pull tensorflow/serving
复制代码


在启动该 docker container 后,也仅需一行命令就可启动模型的 serving api:


tensorflow_model_server --port=8500 --rest_api_port=8501 \  --model_name=${MODEL_NAME} --model_base_path=${MODEL_BASE_PATH}/${MODEL_NAME}
复制代码


这里仅需注意之前保存模型的路径即可。


当然,要搭建一套完整的 FensorFlow Serving 服务并不是一件容易的事情,因为其中涉及到模型更新,整个 Docker 容器集群的维护和按需扩展等一系列工程问题;此外,TensorFlow Serving 的性能问题也仍被业界诟病。但 Tensorflow Serving 的易用性和对复杂模型的支持仍使其是上线 TensorFlow 模型的第一选择。


总结

深度学习 CTR 模型的线上 serving 问题是非常复杂的工程问题,因为其与公司的线上服务器环境、硬件环境、离线训练环境、数据库/存储系统都有非常紧密的联系。正因为这样,各家采取的方式也都各不相同。可以说在这个问题上,即使本文已经列出了 4 种主要的上线方法,但也无法囊括所有业界的 CTR 模型上线方式。甚至于在一个公司内部,针对不同的业务场景,模型的上线方式也都不尽相同。


因此,作为一名算法工程师,除了应对主流的模型部署方式有所了解之外,还应该针对公司客观的工程环境进行综合权衡后,给出最适合的解决方案。


《深度学习 CTR 预估模型实践》专栏内容回顾:


  1. 深度学习 CTR 预估模型凭什么成为互联网增长的关键?

  2. 前深度学习时代CTR预估模型的演化之路——从LR到FFM

  3. 盘点前深度学习时代阿里、谷歌、Facebook的CTR预估模型

  4. 谷歌、阿里等 10 大深度学习 CTR 模型最全演化图谱

  5. 推荐系统工程师必看!Embedding 技术在深度学习 CTR 模型中的应用

  6. CTR预估问题没有“银弹”,比模型结构更重要的是什么?


作者介绍:


王喆,毕业于清华大学计算机系,现在美国最大的 smartTV 公司 Roku 任 senior machine learning engineer,曾任 hulu senior research SDE,7 年计算广告、推荐系统领域业界经验,相关专利 3 项,论文 7 篇,《机器学习实践指南》、《百面机器学习》作者之一。知乎专栏/微信公众号:王喆的机器学习笔记。


2019 年 8 月 10 日 14:043084

评论

发布
暂无评论
发现更多内容

推荐 16 款 IDEA 插件,让你的开发速度飞起来!

Bruce Duan

idea插件

一个好用的工作生活平衡方式

泰稳@极客邦科技

敏捷软件开发宣言及十二原则

BigYoung

敏捷开发

干货分享丨玩转物联网IoTDA服务系列四-智能网关

华为云开发者社区

物联网 智能设备 应用场景 华为云 mqtt

上海首批金融科技“监管沙盒”应用名单出炉 区块链技术备受青睐

CECBC区块链专委会

金融科技 金融监管 创新与安全 智能多元化

国产开源流媒体SRS4.0对视频监控GB28181的支持

潇湘落木

音视频 云直播 短视频 流媒体

Go: 通过代码学习 Map 的设计 — Part II

陈思敏捷

go golang map

胡继晔:发挥我国优势把依法治网落实到区块链管理中

CECBC区块链专委会

CECBC 胡继晔 依法治网 数字货币监管

Flink Weekly | 每周社区动态更新

Apache Flink

flink

阿里巴巴大规模应用 Flink 的实战经验:常见问题诊断思路

Apache Flink

flink

Linux服务器存在某进程CPU过高如何追溯其问题根源?

Nick

Java Linux centos

正则表达式基础详解

懒猫

Java 正则表达式 前端 前端开发 正则

[POJ 1002] 487-3279 C++解题报告

一直AC一直爽

POJ ACM

Vue 学习笔记-3

多选参数

vue.js Vue vuejs

IO系列——用户空间与内核空间

Java联盟

io 零拷贝 用户空间 内核空间 zero copy

一文带你了解Zookeeper所有核心概念

小隐乐乐

zookeeper 分布式 分布式架构

Spring Boot + Vue前后端分离项目,Maven自动打包整合

xcbeyond

maven 前后端分离 springboot 部署

英特尔中国研究院宋继强:芯片、系统、软件成为异构计算的三层级

最新动态

API接口限流

Bruce Duan

分布式限流 单体限流 限流算法

Kafka两个高性价比的参数调优

大数据学徒

Java 大数据 kafka

报志愿|想学区块链,要上什么大学?报什么专业?

CECBC区块链专委会

高考 报考志愿 区块链专业 高校学院

主宰操作系统的经典算法

cxuan

后端 操作系统

Nginx 限流配置

Bruce Duan

Nginx限流

ARTS 第 5 周

乌拉里

Vue 学习笔记-2

多选参数

vue.js Vue vuejs

IO系列——UNIX五种IO模型

Java联盟

io 多路复用 异步IO

架构师那些不能碰的禁忌

曲水流觞TechRill

架构师

CDN百科第七期 | 关于CDN的原理、术语和应用场景那些事

阿里云Edge Plus

CDN

节约60%成本!虎牙直播云端大数据是怎么做到的?

小小的一朵云

如何消灭飞机的“黑色十分钟”,AI来帮忙

华为云开发者社区

华为 AI 智能时代 模型 华为云

HTTPS详解

Bruce Duan

https 对称加密 非对称加密

DNSPod与开源应用专场

DNSPod与开源应用专场

推荐系统工程难题:如何做好深度学习CTR模型线上Serving-InfoQ