diff --git a/chapter_recommender_system/overview.md b/chapter_recommender_system/overview.md index d78f775..625e0df 100644 --- a/chapter_recommender_system/overview.md +++ b/chapter_recommender_system/overview.md @@ -2,6 +2,7 @@ 为了方便本节的讨论,我们首先简单介绍一些推荐系统的基本概念,包括三部分:推荐模型的结构,推荐系统的架构,和评估推荐系统的关键指标。 +### 推荐模型 基于深度学习的推荐模型在过去几年受到了学术界和工业界的高度关注,得到了快速发展。目前主流的推荐模型 :cite:`10.1145/2988450.2988454,10.1145/3124749.3124754,ijcai2017-239,naumov2019deep`的基本结构可以总结如图 :numref:`ch10-recommendation-models`。 ![推荐模型的基本结构](../img/ch10/ch10-recommendation-models.svg) @@ -9,27 +10,29 @@ :label:`ch10-recommendation-models` -推荐模型以用户和内容的交互历史、用户属性、内容属性等特征作为输入,对输入特征进行充分相互作用,再将交互结果交由稠密深度神经网络来预测用户点击候选内容的可能性。为了加深读者的对推荐模型的理解,此处我们以Wide & Deep模型 :cite:`10.1145/2988450.2988454`作为例子,深入分析推荐模型的输入特征以及输入特征之间如何交互。由于推荐模型的设计不在本章的讨论范围内,所以下面的介绍中重点介绍模型的基本结构以方便理解推荐系统的设计,而不讨论Wide & Deep模型的设计理念、数据生成、数据预处理的方法。感兴趣的读者可以自行阅读论文以进一步了解。 +推荐模型以用户和内容的交互历史、用户属性、内容属性等特征作为输入,另输入特征进行充分相互作用,再将交互结果交由稠密深度神经网络来预测用户点击候选内容的可能性。为了加深读者的对推荐模型的理解,此处我们以Wide & Deep模型 :cite:`10.1145/2988450.2988454`作为例子,深入分析推荐模型的输入特征以及输入特征之间如何交互。由于推荐模型的设计不在本章的讨论范围内,所以下面的介绍中重点介绍模型的基本结构以方便理解推荐系统的设计。对Wide & Deep模型的设计理念、数据生成、数据预处理等细节感兴趣的读者可以自行阅读论文以进一步了解。 -Wide & Deep模型是一个设计简洁然而性能优异的模型,由谷歌在开发并应用于谷歌应用商店中,该模型在谷歌的实际生产环境中可以大幅提升应用的下载率。 +Wide & Deep模型是一个设计简洁然而性能优异的模型,由谷歌(Google)在开发并应用于谷歌应用商店中,该模型在谷歌的实际生产环境中可以大幅提升应用的下载率。 Wide & Deep模型的输入数据可以分为两类:连续特征(例如:用户年龄、用户已安装的应用数量、用户参与的会话数量等)和类别特征(例如:用户ID,用户性别属性、用户设备类型、应用ID等)。连续特征的值本身是具有实际意义的数字,可以直接参与后续模型的运算。而类别特征的值并不具有实际意义,所以需要使用嵌入表(Embedding table)将类别特征转化为数字向量,即嵌入项(Embedding item)。 -Wide & Deep模型对输入数据进行两部分处理:Wide部分和Deep部分。Wide部分计算用户已安装应用和候选应用的外积(Cross- product)。Deep部分将所有连续特征和类别特征的嵌入项拼接起来输入一个多层感知机(Multilayer perceptron)。Wide部分和Deep部分按照一定规则拼接然后得到最终的输出。 +Wide & Deep模型对输入数据进行两部分处理:Wide部分和Deep部分。Wide部分计算用户已安装应用和候选应用的外积(Cross-product)。Deep部分将所有连续特征和类别特征的嵌入项拼接起来输入一个多层感知机(Multilayer perceptron)。Wide部分和Deep部分按照一定规则拼接然后得到最终的输出。 +### 推荐系统 -正如上面的例子所示,推荐模型的输入中包含大量无法直接进行矩阵运算的类别数据,而由于每种类别数据包含的每种情况都需要一个单独的嵌入项来表示,而稠密深度神经网络的参数可以共享,在大规模推荐模型中,嵌入表占据了绝大部分内存 :cite:`MLSYS2021_979d472a,MLSYS2020_f7e6c855`。举例说明,假设一个推荐模型需要处理1亿条短视频内容,而每条短视频对应的嵌入项为一个64维的32位浮点数向量,那么仅该内容嵌入表就需要就需要占据大约24GB内存。如果考虑到用户标识符等其他嵌入表,那么单个模型可以轻易占据近100GB内存。而在工业界生产环境中,TB级的推荐模型 :cite:`MLSYS2020_f7e6c855`也是非常常见的。 +在实际的生产环境中,除了推荐模型本身,推荐系统通常包括:数据收集、数据处理、数据存储、模型训练、模型存储、模型评估、推理服务等多个子系统。如图 :numref:`ch10-abstract-recommendation-systems`所示,这些子系统之间分工协作、紧密配合,构成一个从用户反馈、到模型更新、再到新推荐结果生成的闭环。下一小节中将以英伟达(NVIDIA)公司的Merlin开源框架 :cite:`Merlin`为例,概括介绍推荐系统流水线上的组件,并重点介绍模型训练、推理子系统的结构。 - -在实际的生产环境中,除了推荐模型本身,推荐系统通常包括:数据收集、数据处理、数据存储、模型训练、模型存储、模型评估、推理服务等多个子系统。如图 :numref:`ch10-abstract-recommendation-systems`所示,这些子系统之间分工协作、紧密配合,构成一个从用户反馈、到模型更新、再到新推荐结果生成的闭环。下一小节中将重点介绍模型训练、推理子系统的结构。 - -![推荐系统的抽象架构](../img/ch10/ch10-abstract-recommendation-systems.svg) +![推荐系统的基本组件](../img/ch10/ch10-abstract-recommendation-systems.svg) :width:`800px` :label:`ch10-abstract-recommendation-systems` -深度学习模型给出的推荐结果的准确性是推荐系统需要关注的一个基本指标。然而不同于一般学术论文中使用的基准数据集,生产环境中推荐模型面对的是动态变化的数据分布。例如,每天的热点内容不同,每个用户的兴趣也会不断变化。为了保持模型的性能,推荐系统需要不断根据用户的反馈对已有模型进行更新。而这就需要系统能够将用户的行为转换为模型可以处理的数据。系统首先在提供服务的同时收集用户的行为,例如用户对内容的浏览、点击动作。收集到的数据还需要进一步加工处理,从而得到模型可以接受的格式化数据。 +### 关键指标 -除了推荐准确性,对于在线服务的提供者而言,可用性是一个非常关键的指标。当用户需要一个推荐结果时,相比于给用户一个不完全准确的推荐,"无响应"的结果对于用户的体验伤害更大。因此,在某种程度上可以说系统可用性是比推荐结果的准确性更加关键的一个指标。然而这并不意味着准确性不重要,在一定的资源限制下,在线推荐系统的设计者必须谨慎地在准确性和可用性之间进行平衡。例如,使用更宽、更深、更复杂的神经网络模型可能会给出更加准确的推荐结果,但如果其推断延迟高于给定的阈值,那么这样的模型不能直接运用于生产环境中。 \ No newline at end of file +- **准确性:** + 深度学习模型给出的推荐结果的准确性是推荐系统需要关注的一个基本指标。然而不同于一般学术论文中使用的基准数据集,生产环境中推荐模型面对的是动态变化的数据分布。例如,每天的热点内容都不尽相同,而且每个用户的兴趣也会不断变化。为了保持模型的性能,推荐系统需要不断根据用户的反馈对已有模型进行更新。 + +- **可用性:** + 除了推荐准确性,对于在线服务的提供者而言,可用性是一个非常关键的指标。当用户需要一个推荐结果时,相比于给用户一个不完全准确的推荐,"无响应"的结果对于用户的体验伤害更大。因此,在某种程度上可以说系统可用性是比推荐结果的准确性更加关键的一个指标。然而这并不意味着准确性不重要,在一定的资源限制下,在线推荐系统的设计者必须谨慎地在准确性和可用性之间进行平衡。例如,使用更宽、更深、更复杂的神经网络模型可能会给出更加准确的推荐结果,但如果其推断延迟高于给定的阈值,那么这样的模型不能直接运用于生产环境中。 \ No newline at end of file diff --git a/chapter_recommender_system/system_architecture.md b/chapter_recommender_system/system_architecture.md index 41aaa39..a9f1361 100644 --- a/chapter_recommender_system/system_architecture.md +++ b/chapter_recommender_system/system_architecture.md @@ -1,12 +1,20 @@ ## 主流系统架构 -正如上文提到的,嵌入表占据了推荐模型绝大部分存储而其更新具有显著的稀疏性,因此推荐系统通常采用上一章介绍的参数服务器架构来存储模型。具体来讲,所有参数被分布存储在一组参数服务器上,而训练服务器一方面从数据存储模块拉取训练数据,另一方面根据训练数据从参数服务器上拉取对应的嵌入项和所有稠密神经网络参数。训练服务器本地更新之后将本地梯度或新的参数发送回参数服务器以更新全局参数。全局参数更新可以选择全同步,半同步,或异步更新。类似的,推理服务器在接到一批用户的推荐请求后,从参数服务器拉去相应的嵌入项和稠密神经网络参数来响应用户的请求。为了提升训练(推理)的吞吐,可以在训练(推理)服务器上缓存一部分参数。 +在实际的生产环境中,除了推荐模型本身,一个企业级推荐系统通常包括从用户反馈数据收集,到模型训练,再到服务用户请求的完整流水线(pipeline)。甚至从系统角度来看,推荐模型固然是系统的核心,然而其本身的代码仅占推荐系统的很小一部分,而围绕推荐模型所构建的其他基础设施占据了系统的绝大部分 :cite:`NIPS2015_86df7dcf`。 -为了避免训练服务器和参数服务器之间的通信限制训练吞吐率,一些公司也在探索单机多GPU训练超大规模推荐系统。然而正如前文提到的,即使是单个推荐模型的参数量(~100GB)也超出了目前最新的GPU显存。有鉴于此,脸书公司的定制训练平台 --- ZionEX :cite:`zionex`利用计算设备之间的高速链接将多台设备的存储共享起来可以单机训练TB级推荐模型。然而对于更大规模的模型或中小型企业、实验室,参数服务器架构依然是性价比最高的解决方案。 -为了提升在发生故障的情况下的可用性,在线服务中的深度学习推荐模型通常都采用多副本分布式部署。同一个模型的多个副本通常会被部署在至少两个不同的地理区域内的多个数据中心中,如图 :numref:`ch10-recommendation-systems`,以应对大面积停电或者网络中断而导致整个地区的所有副本都不可用。除了容错方面的考虑,部署多个副本还有其他几点优势。首先,将模型部署在靠近用户的云服务器上可以提升响应速度。其次,部署多份副本也可以拓展模型推理服务的吞吐率。 +本节以英伟达公司的Merlin开源框架 :cite:`Merlin`为例,简单介绍推荐系统的完整流水线以及各个组件在其中的作用,关于Merlin特性的完整介绍请读者参考官方文档。 +Merlin是英伟达公司开发的一个开源推荐系统框架,帮助使用者构建高效的、基于GPU的推荐系统。Merlin提供三个主要开源组件:NVTabular :cite:`NVTabular`,HugeCTR :cite:`HugeCTR`和Triton :cite:`Triton`,分别对数据处理、模型训练核推理服务进行端到端加速。下面分别展开介绍流水线中的三个主要环节: + +1. 数据处理:推荐系统首先从用户的推荐请求中记录用户的反馈数据(例如,用户是否对推荐结果做出了正向反应)到数据存储系统中。随后数据预处理系统对原始反馈数据进行格式化、清洗、重采样等操作生成训练数据。关于数据处理组件,本书在前面章节进行了详细介绍。在Merlin中,这一步骤由NVTabular负责。同时NVTabular还为多种模型训练框架提供了数据加载器(dataloader)。 +2. 模型训练:推荐模型每次迭代选择一批训练数据,拉取对应的嵌入项、并送入稠密神经网络,计算损失,然后反向传播计算梯度,最终更新嵌入表和稠密神经网络。正如上文提到的,嵌入表占据了推荐模型绝大部分存储而其更新具有显著的稀疏性,因此推荐系统通常采用上一章介绍的参数服务器架构来存储模型。具体来讲,所有参数被分布存储在一组参数服务器上,而训练服务器根据训练数据从参数服务器上拉取对应的嵌入项和所有稠密神经网络参数。训练服务器本地更新之后将本地梯度或新的参数发送回参数服务器以更新全局参数。全局参数更新可以选择全同步,半同步,或异步更新。为了提升训练的吞吐,可以在训练服务器上缓存一部分参数。HugeCTR为此提供了Embedding Training Cache和GPU embedding cache。为了避免训练服务器和参数服务器之间的通信限制训练吞吐率,一些公司也在探索单机多GPU训练超大规模推荐系统。然而正如前文提到的,即使是单个推荐模型的参数量(~100GB)也超出了目前最新的GPU显存。有鉴于此,脸书(Facebook)公司的定制训练平台 -- ZionEX :cite:`zionex`利用计算设备之间的高速链接将多台设备的存储共享起来可以单机训练TB级推荐模型。然而对于更大规模的模型或中小型企业、实验室,参数服务器架构依然是性价比最高的解决方案。 +3. 推理服务:类似地,推理服务器在接到一批用户的推荐请求后,从参数服务器拉去相应的嵌入项和稠密神经网络参数来响应用户的请求。推荐系统的推理服务对延迟十分敏感,例如脸书公司的DLRM :cite:`naumov2019deep`基准在MLPerf评测中的服务器延迟限定在30ms[^1]。因此如何在限定延迟(latency-bounded)的情况下尽可能提升吞吐(throughput)是推理服务面临的关键问题。在GPU推理场景下,常见的优化手段有:请求动态合批处理、核融合、低精度部署等 :cite:`10.1145/3437801.3441578,wang-etal-2021-lightseq`. Triton提供了请求调度的功能并且支持多种不同的机器学习框架作为后端。 + + +在工业界,为了提升系统在发生故障的情况下的可用性,以上介绍的各个组件在实际中部署中都应该具备基本的容灾和故障恢复能力。以推理服务为例,在线服务中的深度学习推荐模型通常都采用多副本分布式部署。同一个模型的多个副本通常会被部署在至少两个不同的地理区域内的多个数据中心中,如图 :numref:`ch10-recommendation-systems`,以应对大面积停电或者网络中断而导致整个地区的所有副本都不可用。除了容错方面的考虑,部署多个副本还有其他几点优势。首先,将模型部署在靠近用户的云服务器上可以提升响应速度。其次,部署多份副本也可以拓展模型推理服务的吞吐率。 ![推荐系统的分布式架构](../img/ch10/ch10-recommendation-systems.svg) :width:`800px` :label:`ch10-recommendation-systems` + +[^1]: https://mlcommons.org/en/inference-datacenter-11/ \ No newline at end of file diff --git a/chapter_recommender_system/system_problem.md b/chapter_recommender_system/system_problem.md index 1629332..71e33aa 100644 --- a/chapter_recommender_system/system_problem.md +++ b/chapter_recommender_system/system_problem.md @@ -2,7 +2,8 @@ 在线服务系统的两个主要诉求: -- 大模型的高效存储。为了提升训练和推理的性能,通常推荐模型全部存储在内存中,然而纯内存存储对于内存的需求极高。正如前文分析的,单个模型就要占据至少100GB的内存,而一个在线推荐系统中需要同时运行多个模型负责不同的服务。如果考虑到除了在线服务模型,算法研究人员还需要上线测试不同的模型结构或者训练策略,系统中通常会同时存在上百个超大模型。因此在线推荐系统亟需既能拓展存储容量,又不会影响训练和推理性能的存储解决方案。 +- 大模型的高效存储。 + 为了提升训练和推理的性能,通常推荐模型全部存储在内存中,然而纯内存存储对于内存的需求极高。推荐模型的输入中包含大量无法直接进行矩阵运算的类别数据,而由于每种类别数据包含的每种情况都需要一个单独的嵌入项来表示,而稠密深度神经网络的参数可以共享,在大规模推荐模型中,嵌入表占据了绝大部分内存 :cite:`MLSYS2021_979d472a,MLSYS2020_f7e6c855`。举例说明,假设一个推荐模型需要处理1亿条短视频内容,而每条短视频对应的嵌入项为一个64维的32位浮点数向量,那么仅该内容嵌入表就需要就需要占据大约24GB内存。如果考虑到用户标识符等其他嵌入表,那么单个模型可以轻易占据近100GB内存。而在工业界生产环境中,TB级的推荐模型 :cite:`MLSYS2020_f7e6c855`也是非常常见的。此外,在线推荐系统中需要同时运行多个模型负责不同的服务,甚至同一个服务也会上线多个模型以供算法开发人员验证不同的模型结构或者训练策略,因此系统中通常会同时存在上百个超大模型。综上所述,在线推荐系统亟需既能拓展存储容量,又不会影响训练和推理性能的存储解决方案。 - 大模型的快速更新。 在线服务系统所面对的环境是复杂多变的,因此其中的机器学习模型必须不断更新以应对新的数据分布。以一个短视频推荐系统为例,其面对的变化主要来自三点。首先,每时每刻都有大量的新视频上传,这些新视频的特征分布和模型训练时所见到的数据不同;其次,对于不断加入的新用户,模型难以直接给出最优的推荐结果;最后,全部用户和内容之间的交互在不断改变,表现为热点视频在持续变化。因此,为了应对以上变化,在线服务中不可能奢望仅仅训练一次模型就能够一劳永逸地解决问题。目前业界主流的做法是利用新产生的数据不断地增量式更新所部属的模型。在学术界和工业界大量的研究和实践 :cite:`10.1145/2020408.2020444,10.1145/2648584.2648589,10.1145/3267809.3267817,9355295`中都发现模型更新可以有效缓解概念漂移带来的危害,而且更新的频率越高,模型的性能越好。 diff --git a/mlsys.bib b/mlsys.bib index e255784..787516a 100644 --- a/mlsys.bib +++ b/mlsys.bib @@ -755,4 +755,84 @@ series = {ADKDD'17} author={Naumov, Maxim and Mudigere, Dheevatsa and Shi, Hao-Jun Michael and Huang, Jianyu and Sundaraman, Narayanan and Park, Jongsoo and Wang, Xiaodong and Gupta, Udit and Wu, Carole-Jean and Azzolini, Alisson G and others}, journal={arXiv preprint arXiv:1906.00091}, year={2019} +} + +@inproceedings{NIPS2015_86df7dcf, + author = {Sculley, D. and Holt, Gary and Golovin, Daniel and Davydov, Eugene and Phillips, Todd and Ebner, Dietmar and Chaudhary, Vinay and Young, Michael and Crespo, Jean-Fran\c{c}ois and Dennison, Dan}, + booktitle = {Advances in Neural Information Processing Systems}, + editor = {C. Cortes and N. Lawrence and D. Lee and M. Sugiyama and R. Garnett}, + pages = {}, + publisher = {Curran Associates, Inc.}, + title = {Hidden Technical Debt in Machine Learning Systems}, + url = {https://proceedings.neurips.cc/paper/2015/file/86df7dcfd896fcaf2674f757a2463eba-Paper.pdf}, + volume = {28}, + year = {2015} +} + +@misc{Merlin, + note={Accessed on 2022-03-24}, + author = {NVIDIA}, + year = {2022}, + title = {{{NVIDIA Merlin}}}, + howpublished = {\url{https://github.com/NVIDIA-Merlin/Merlin}}, +} + +@misc{NVTabular, + note={Accessed on 2022-03-24}, + author = {NVIDIA}, + year = {2022}, + title = {{{NVIDIA NVTabular}}}, + howpublished = {\url{https://github.com/NVIDIA-Merlin/NVTabular}}, +} + +@misc{HugeCTR, + note={Accessed on 2022-03-24}, + author = {NVIDIA}, + year = {2022}, + title = {{{NVIDIA HugeCTR}}}, + howpublished = {\url{https://github.com/NVIDIA-Merlin/HugeCTR}}, +} + +@misc{Triton, + note={Accessed on 2022-03-24}, + author = {NVIDIA}, + year = {2022}, + title = {{{NVIDIA Triton}}}, + howpublished = {\url{https://github.com/triton-inference-server/server}}, +} + +@inproceedings{10.1145/3437801.3441578, +author = {Fang, Jiarui and Yu, Yang and Zhao, Chengduo and Zhou, Jie}, +title = {TurboTransformers: An Efficient GPU Serving System for Transformer Models}, +year = {2021}, +isbn = {9781450382946}, +publisher = {Association for Computing Machinery}, +address = {New York, NY, USA}, +url = {https://doi.org/10.1145/3437801.3441578}, +doi = {10.1145/3437801.3441578}, +abstract = {The transformer is the most critical algorithm innovation of the Nature Language Processing (NLP) field in recent years. Unlike the Recurrent Neural Network (RNN) models, transformers are able to process on dimensions of sequence lengths in parallel, therefore leads to better accuracy on long sequences. However, efficient deployments of them for online services in data centers equipped with GPUs are not easy. First, more computation introduced by transformer structures makes it more challenging to meet the latency and throughput constraints of serving. Second, NLP tasks take in sentences of variable length. The variability of input dimensions brings a severe problem to efficient memory management and serving optimization.To solve the above challenges, this paper designed a transformer serving system called TurboTransformers, which consists of a computing runtime and a serving framework. Three innovative features make it stand out from other similar works. An efficient parallel algorithm is proposed for GPU-based batch reduction operations, like Softmax and LayerNorm, which are major hot spots besides BLAS routines. A memory allocation algorithm, which better balances the memory footprint and allocation/free efficiency, is designed for variable-length input situations. A serving framework equipped with a new batch scheduler using dynamic programming achieves the optimal throughput on variable-length requests. The system can achieve the state-of-the-art transformer model serving performance on GPU platforms and can be seamlessly integrated into your PyTorch code with a few lines of code.}, +booktitle = {Proceedings of the 26th ACM SIGPLAN Symposium on Principles and Practice of Parallel Programming}, +pages = {389–402}, +numpages = {14}, +keywords = {serving system, deep learning runtime, GPU, transformers}, +location = {Virtual Event, Republic of Korea}, +series = {PPoPP '21} +} + +@inproceedings{wang-etal-2021-lightseq, + title = "{L}ight{S}eq: A High Performance Inference Library for Transformers", + author = "Wang, Xiaohui and + Xiong, Ying and + Wei, Yang and + Wang, Mingxuan and + Li, Lei", + booktitle = "Proceedings of the 2021 Conference of the North American Chapter of the Association for Computational Linguistics: Human Language Technologies: Industry Papers", + month = jun, + year = "2021", + address = "Online", + publisher = "Association for Computational Linguistics", + url = "https://aclanthology.org/2021.naacl-industry.15", + doi = "10.18653/v1/2021.naacl-industry.15", + pages = "113--120", + abstract = "Transformer and its variants have achieved great success in natural language processing. Since Transformer models are huge in size, serving these models is a challenge for real industrial applications. In this paper, we propose , a highly efficient inference library for models in the Transformer family. includes a series of GPU optimization techniques to both streamline the computation of Transformer layers and reduce memory footprint. supports models trained using PyTorch and Tensorflow. Experimental results on standard machine translation benchmarks show that achieves up to 14x speedup compared with TensorFlow and 1.4x speedup compared with , a concurrent CUDA implementation. The code will be released publicly after the review.", } \ No newline at end of file