CategoryResourceRepost/极客时间专栏/深度学习推荐系统实战/前沿拓展篇/33|技术权衡:解决方案这么多,哪个最合适?.md
louzefeng d3828a7aee mod
2024-07-11 05:50:32 +00:00

130 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<audio id="audio" title="33技术权衡解决方案这么多哪个最合适" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/75/17/757b0a1fa0aa32afc330d9687cd38317.mp3"></audio>
你好,我是王喆。
在实际的工作中我们经常会面临一些技术上的抉择。比如说在设计推荐系统的时候我们是应该用模型A还是用模型B是用TensorFlow还是用PyTorch是用Redis还是用EVCache呢从理论上来说其实选择哪个方案都可以但在工程落地中不同的方案往往对系统整体的开销整个团队的工作量甚至最终的推荐效果都有着非常大的影响。
我想这也是很多算法工程师的困惑:在工程落地环节,解决方案这么多,我们到底该选哪个?
今天,我们就一起来探讨一下技术权衡的问题,看看能不能在理论知识和工程落地之间找到一条最优的路径。
## 工程师职责的本质
“工程”和“理论”之间的权衡是所有工程师都要考虑的问题,对这个问题的思考方式决定了你具备的是“工程思维”还是“研究思维”,抑或是“学生思维”。推荐系统是一个工程性极强,以技术落地为首要目标的领域,因此,“工程思维”对推荐系统工程师是最重要的。
事实上,无论是算法工程师,还是研发工程师,甚至是设计电动汽车、神舟飞船、长征火箭的工程师,他们的职责都相同,那就是**在现有实际条件的制约下,以工程完成和技术落地为目标,寻找并实现最优的解决方案。**这里面有一个词最关键,那就是“制约”。我们该怎么理解这个制约呢?
比如说,在机器学习的理论层面,一切事情都是理想化的,就像模型结构是精确定义的,训练过程是严格推导的,但在实际条件下,一个模型的训练过程会受算力条件、数据质量、工程时间限制等多重条件的制约。这也是我们不得不面临诸多选择和权衡的原因。
再比如说我有些同学在航天领域工作最近趁着嫦娥五号任务圆满完成的热点我咨询了他们一个问题说“咱们国家什么时候能实现载人登月啊”他们这帮航天工程师的回答也很严谨说“制约咱们国家载人登月的主要是火箭的运力问题现在的长征五号火箭近地轨道运载能力是25吨美国阿波罗登月计划使用的土星五号火箭的轨道运载能力是140吨整整差了5倍多。”
[<img src="https://static001.geekbang.org/resource/image/52/bb/5206160f389c023852a5980dafd095bb.jpeg" alt="" title="图1 土星五号和长征5号">](https://www.bilibili.com/video/av71595679/)
你看,所有的工程师都在受客观条件的制约,那怎么办呢?他们又讲了,要么就是一步步来,先攻克运载火箭技术,再像阿波罗计划一样,一发火箭把登月舱、返回舱、航天员等等一起送到月球;要么就是用现有的长征五号,发射四到五枚火箭,在太空中完成登月舱、返回舱、载人飞船的组装。
第一个计划的优势是一次性搞定,但周期长,需要等待火箭技术的攻克。第二个计划的优势是现在就可以着手开始做,但因为要发射四到五枚火箭,整个任务的容错率低,失败的风险大。
所以你看,航天工作者们发射火箭也成天抱怨运力不够,就像我们训练模型总说算力不够一样。那怎么办,日子就不过了吗?当然不是,我们工程师就是要在这样的制约条件下,又快又好地解决问题、完成任务,这就是你的职责所在。
那推荐系统中“现有实际条件的制约”都有什么呢我们经常会遇到这3种
- 软硬件环境的制约
- 研发周期的制约
- 实际业务逻辑和应用场景的制约
正是因为有这些制约的存在,一名工程师不可能像学术界的研究者一样不断尝试新的技术,做更多探索性的创新,也正是因为工程师永远以“技术落地”为目标,而不是炫耀自己的新模型、新技术是否走在业界前沿,所以在前沿理论和工程现实之间做权衡是一名工程师应该具有的基本素质。
那这个技术权衡具体该怎么做呢?下面,我就借用三个实际的案例帮助你体会一下。
## Redis容量和模型上线方式之间的权衡
对线上推荐系统来说为了进行在线服务需要将特征和模型参数存储到线上数据库或者线上服务器内存中。为了保证这两部分数据的实时性很多公司采用内存数据库的方式实现就像我们在第10讲中讲的一样Redis这类内存数据库自然是主流的选择。
但Redis需要占用大量内存资源而内存资源相比存储资源和计算资源又比较稀缺和昂贵的资源。因此无论是AWSAmazon Web Services亚马逊网络服务平台、阿里云还是自建数据中心实现Redis模块的成本都比较高自然Redis的容量就成了制约推荐系统模型上线方式的关键因素。
在这个制约因素下,我们要考虑两方面的事情:
1. 模型的参数规模要尽量小。特别是对深度学习推荐系统而言,模型的参数量级较传统模型有了几个量级的提升,所以我们更应该着重考虑模型的参数规模;
1. 因为要考虑线上预估延迟和特征存储空间有限的情况,所以线上预估所需的特征数量不能无限制地增加,要根据重要性做一定的删减。
因此,在实际上线推荐系统的时候,我们必然需要进行一定的取舍:**舍弃一些次要的要素,关注主要的矛盾**。具体怎么做呢?这里,我结合自己的经验,把整个取舍的思考过程做了梳理,一共可以分成四步,你可以作为参考。
首先,对于千万量级甚至更高量级的特征向量维度(理论上模型参数的数量级也在千万量级)来说,因为线上服务很难支持这种级别的数据量,所以我们在上线模型时关注模型的稀疏性和复杂度,通过舍弃一定的模型预测准确度来换取上线的速度和资源消耗。
明确了工程权衡的目标我们就要思考怎么提高模型的稀疏性降低模型的复杂度。提高稀疏性的常见方法是加入L1正则化项或者采用FTRL这类稀疏性强的训练方法让大部分参数归零从而减少模型体积。
对于降低复杂度,我们可以通过减少神经网络的层数,以及每层内神经元的数量来实现。当然,这个方法只有在不明显降低模型效果的前提下,才是可行的工程策略。
在明确了多种备选方案之后,如果还是无法确定哪种技术效果更佳,我们就需要实现所有备选方案以及方案间的各种组合,进行离线和线上的效果测试。
最后,我们要根据测试数据确定最终的技术途径、技术方案,完成最终上线。
以上就是模型侧的“瘦身”方法在线特征的“瘦身”方法当然也可以采用同样的思路。首先采用“主成分分析”等方法进行特征筛选在不显著降低模型效果的前提下减少所用的特征。针对不好取舍的特征进行离线评估和线上A/B测试最终达到工程上可以接受的水平。
## 研发周期和平台迁移之间的权衡
除了硬件条件的限制,研发周期的制约同样是不可忽视的因素。这就需要工程师对于项目有整体的把控,以及对研发周期有预估。在产品迭代日益迅速的互联网领域,没人愿意成为拖累整个团队的最慢的一个环节。接下来,我就以一个平台迁移的例子,来给你讲一讲如何在研发周期的制约下完成技术决策。
比如公司希望把机器学习平台从Spark MLlib整体迁移到TensorFlow上毫无疑问这是顺应深度学习浪潮的技术决策是非常正确的决定。但由于Spark平台自身的特性它的编程语言、模型训练方式都和TensorFlow有很大的差别因此整个迁移必然要经历一个较长的研发周期。
我就经历过很多次公司产品和技术平台的大规模升级,很常见的情况是,在保证平台升级正常进行的同时,我们还需要兼顾日常的开发进度,去实现一些新的产品需求。这就是工程师需要做出权衡的时候了,也是最考验工程师架构能力的时候。
<img src="https://static001.geekbang.org/resource/image/57/b2/57b98830369yy8d95fe173a585046fb2.jpeg" alt="" title="图2 TensorFlow vs Spark">
在这样的情况下一般来说有2种可行的技术方案
1. 集中团队的力量完成Spark到TensorFlow的迁移在新平台上进行新模型和新功能的研发。
1. 让团队一部分成员利用成熟稳定的Spark平台快速满足产品需求为TensorFlow的迁移、调试、试运行留足充分的时间。同时让另一部分成员全力完成TensorFlow的相关工作尽量保证新平台的成熟和可靠。
不过单纯从技术角度考虑既然团队已经决定迁移到TensorFlow平台了理论上就没必要再花时间利用Spark平台研发新模型否则到时候还要进行二次开发。但是再成熟的平台也需要整个团队磨合调试较长时间绝不可能刚迁移TensorFlow就让它支持重要的业务逻辑。而且技术平台的升级换代应该作为技术团队的内部项目最好对其他团队是透明的不应该成为减缓对业务支持的直接理由。
因此从工程进度和风险角度考虑第2个技术途径更符合工程实际的需求。
## 冷启动等业务逻辑对推荐模型的制约
最后一类制约是来自业务逻辑,或者说应用场景的,最常见的如物品冷启动问题,这类业务问题往往制约了模型的更新和应用的方式。
之前我们讲了很多种生成物品Embedding的方法但在任何公司业务中物品都不是一成不变的就像视频网站要不断添加新视频电商网站会不断加入新的商品。这个时候新物品的Embedding该如何生成呢
对于Item2vec、DeepWalk这类基于物品节点的Embedding模型来说数据中必须包含新物品的ID才能够生成它相应的Embedding。这就要求我们必须加快模型的更新速度让模型尽快学习新物品的数据。这就是业务场景的特点在倒逼我们改进模型的实时性。这个时候我们就又要思考改进Embedding模型实时性的方法了。
这里,我总结出了下面三个备选方案。
方案一从模型训练pipeline的各个环节入手看看哪些环节可以优化。比如我们可以优化Spark数据预处理的过程加快预处理速度优化Embedding上线的过程让Embedding从产生到上线的过程更紧凑。
方案二:从模型的复杂度入手,看一看能否在不显著伤及效果的前提下,通过降低模型的复杂度来降低训练时间,进而加快模型更新的速度。
方案三跳出End2End训练Embedding模型的限制看看能不能通过其他策略性的手段来生成临时性的新物品Embedding。
其中,前两个方案需要我们从细节入手来优化工程上的实现,而第三个则要求我们有更灵活的处理思路。这一点也是我想和你多聊一聊的。
我们在改进推荐系统的时候不能总陷进机器学习的固定思维里认为一定要用一些机器学习模型或者深度学习网络去解决问题我把这样的思维叫做“技术洁癖”。我们应该清楚的是工程师的第一任务是解决问题而不是搭一个精致好看的技术玩具所以在推荐模型的基础上用一些策略性的手段来修补一些边界情况“bad case”是可以去尝试的。
回到这个物品Embedding冷启动的例子上策略性地生成新物品的Embedding就是很好的补充方式房屋短租行业的巨头Airbnb就给我们提供了一个很好的参考例子。
在Airbnb平台上如果一个新的出租屋发布了但模型还没有学到它的EmbeddingAirbnb的推荐系统会怎么做呢它会通过三个步骤生成新出租屋的Embedding。
第一步根据新房屋的属性比如租金价格、房屋类型、面积、几房几厅等特征来找到和它相似的一批房屋第二步在这些相似房屋中找到离它最近的三个第三步通过平均这三个最近房屋的Embedding来生成新房屋的Embedding。
就像图3展示的这样颜色相近的点代表着Embedding非常接近的房屋如果一个新房屋落在了图中的某个位置Airbnb就可以根据它的地理位置和属性找到相近的房屋并且给它涂上相似的颜色。
<img src="https://static001.geekbang.org/resource/image/8d/2a/8df08c853314f54e20c6a02fc21f672a.jpeg" alt="" title="图3 Airbnb房屋聚类的例子">
所以我们经常会看到,一些推荐系统中的补充策略往往可以高效地解决一些推荐模型无法解决的棘手问题。
当然,在我们日常工作中技术间的权衡无时无刻不在发生,小到一个变量取什么名字好,一行代码应该怎么写,大到一个平台应该怎么重构,一个模型应该如何构建。我们这节课的例子当然无法囊括所有的情况,只是希望能帮助你建立起正确的进行技术权衡的思路,做到抓住主矛盾点,做出有利于主要目标的取舍。
## 小结
这节课,我们通过三个例子一起探讨了工程落地中技术权衡的问题,希望能帮助你进一步加深了对工程师思维本质的理解。
事实上,对任何领域来说,工程师思维的本质都是“**在现有实际条件的制约下,以工程完成和技术落地为目标,寻找并实现最优的解决方案**”。
在推荐系统领域,典型的制约条件有三类:“软硬件环境的制约”,“研发周期的制约”,以及“实际业务逻辑和应用场景的制约”。在这些制约条件下,我认为的技术方案间的权衡之道,就是“抓住主矛盾点,列出备选方案,通过分析对比,作出有利于主要目标的取舍。”
## 课后思考
这节课我们提到了物品冷启动问题的解决方案你觉得基于Embedding还有哪些好的冷启动解决方案呢如果让你来解决的话在实践中你会作出哪些取舍倾向于哪种选择呢
期待在留言区看到你的分享和思考,我们下节课见!