飞桨框架 2.0 版本基于工业实践,创新性地
推出了大规模稀疏异构
参数服务器功能。
眼看着就要到「双 11」就要到了,对于广大网购爱好者来说那绝对是不可错过的狂欢时刻!当今网购之所以如此火爆,不仅仅是营销策划的作用,智能化的搜索推荐技术也可以说是功不可没。它能把你日思夜想或者潜意识中动过购买念头的商品通通推送到你的面前,甚至会让人有一种冥冥自有天意、不买对不起上苍的感觉。而这背后往往都会有深度学习领域中个性化推荐模型发挥着威力。为了能够更准确的预知用户的内心需求,快速
训练出效果良好的推荐模型并尽快部署上线,成为了各大网购业务相关企业的共同追求。
在搜索推荐领域中,通常推荐模型的网络并不复杂,但是由于对应的特征空间大,所以通常会使用算力要求不高但是规模非常庞大的 Embedding 和 FC 层来将用户及商品的高维稀疏特征向量转化为低维的稠密特征向量,导致这类模型的
参数维度可以达到千亿甚至万亿级别,并且还伴随着大规模稀疏的特点。同时各个企业为了模型效果,往往会使用尽可能多的数据来
训练模型,尤其是其中的点击数据,如果来自一些带有「选择困难症」的人,可能会非常的长,导致数据规模愈加庞大,甚至可以达到亿级。因此,相比 CV 和 NLP 领域而言,在搜索推荐场景中,单次 Batch 训练中前后向计算的时间远低于数据读取、拉取和更新参数等过程的时间,再加上庞大的数据和参数量,导致内存要求很高,甚至可以达到几十 T,而拥有这类特点的训练任务通常都被称为 IO 密集型训练任务。
那么如何快速完成 IO 密集型训练任务呢?
单机训练肯定无法承受这样的任务,只有分布式训练才是解决问题的方法。简单来说,分布式训练就是使用多个
硬件设备共同完成训练任务,可以分为 All-Reduce Collective 和 Parameter Server (参数
服务器)两种训练
架构。
在 Collective
架构中,FC,集群中存在多个地位平等的 Trainer(也可以叫 Worker)。在数据并行的方式下,每个 Trainer 上都保存一份完整的模型网络结构和模型参数,在前向和反向计算过程中,每个 Trainer 使用自己划分的数据(shard)进行计算,得到对应的梯度;然后 Trainer 之间通过 All-Reduce 等通信方式同步梯度到所有 Trainer,最后每个 Trainer 使用同步后的梯度独立完成参数更新。
图 1:Collective 架构
由于推荐搜索领域模型的 Embedding 层规模庞大以及训练数据样本长度不固定等原因,导致容易出现显存不足和卡间同步时间耗费等问题,所以 Collective 架构很少被用于搜索推荐领域。
再来看看参数服务器架构。与 Collective 相比,参数服务器架构中除了 Trainer 之外还有一个角色叫 Server。在执行前向与反向计算过程中,Server 负责从各个 Trainer 收集汇总梯度,然后使用这些梯度信息计算更新参数,并向各个 Trainer 分发更新后的参数信息。
图 2:传统参数服务器架构
但是在应对 IO 密集型任务时,传统参数服务器模式会出现以下问题:
如果使用的是 CPU 机器作 Trainer,通常 CPU 核心数较多,且购置价格便宜,训练中可以充分利用 CPU 多核的优势,使用异步训练模式,在简单模型上可以极大提升数据吞吐量,对提升整体训练速度有不俗的表现。但是 AI 开发者为了追求模型效果开始逐步在推荐模型中增加复杂网络部分,CPU 计算能力的弱势便暴露无遗,NES,训练耗时会变得不可接受。
图 3:传统参数服务器架构(CPU 机器)遇到算力瓶颈
如果更新集群
硬件,改为使用的是 GPU 机器作 Trainer,则可能会出现资源利用率低和网络带宽不足的问题:
资源利用率低:IO 密集型任务主要还是数据读取和模型读取 (IO) 的性能对训练速度更具决定性。在这方面使用 GPU 的集群如同「杀鸡用牛刀」,并不会对整体的训练速度产生多少帮助,而且硬件资源得不到充分利用。而如果加大 Batchsize 提高单次前向后向计算占比,也会受到单机 IO 吞吐能力的制约,而且由于模型高度稀疏,模型效果也会受到影响。