10

十行代码让你的单机“影分身”,分布式训练速度快到飞起

 3 years ago
source link: https://my.oschina.net/u/4067628/blog/4867225
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
十行代码让你的单机“影分身”,分布式训练速度快到飞起 - 飞桨PaddlePaddle的个人空间 - OSCHINA - 中文开源技术交流社区

工程师:“在你辉煌的时刻,让我为你唱首歌,我的好兄弟,心里有苦你对我说。”

计算机:“哥啊,那我可就说了,我是真的苦啊,现在一个模型动辄好几亿参数,数据集也是大的吓人,兄弟我内存都快被掏空了,实在训练不动了呀。”

工程师:“前方大路一起走,哪怕是河也一起过…”

计算机:“你怎么还唱啊,兄弟我真的坚持不住了。”

工程师:“担心啥,哥有的是办法救你,就这招吧——分布式训练之参数服务器!”

计算机:“分布式训练?参数服务器?真的很好用吗?”

工程师:“好吧,接下来我们就来看看什么是分布式训练参数服务器功能。”

下载安装命令

## CPU版本安装命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle

## GPU版本安装命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu

什么是分布式训练

何谓分布式训练呢?大家想想《火影忍者》中鸣人搓螺旋丸的方法,要知道鸣人一个人可搓不出来,他是怎么做的呢?对!影分身,再变出两个分身来帮他一起搓丸子,分布式训练其实用的是相同的原理。通俗的讲就是把原先交给一台计算机上完成的训练任务改为交由多台计算机完成。每台计算机上都会有一个或多个计算单元,例如CPU、GPU、AI芯片等,合作的计算机越多,参与训练的计算单元也就越多。可想而知那速度肯定是噌噌的!

什么是参数服务器

如图1所示,参数服务器是分布式训练领域普遍采用的编程架构,主要包含Server和Worker两个部分,其中Server负责参数的存储和更新,而Worker负责训练。飞桨的参数服务器功能也是基于这种经典的架构进行设计和开发的,同时在这基础上进行了SGD(Stochastic Gradient Descent)算法的创新(Geometric Stochastic Gradient Descent)。当前经过大量的实验验证,最佳的方案是每台机器上启动Server和Worker两个进程,而一个Worker进程中可以包含多个用于训练的线程。

图1 参数服务器架构示意图

飞桨参数服务器功能支持三种模式,分别是同步训练模式、异步训练模式和GEO异步训练模式:

  • 同步训练模式:如图2所示,Worker在训练一个batch的数据后,会合并所有线程的梯度发给Server, Server在收到所有节点的梯度后,会统一进行梯度合并及参数更新。同步训练的优势在于Loss可以比较稳定的下降,缺点是整个训练速度较慢,这是典型的木桶原理,速度的快慢取决于最慢的那个线程的训练计算时间,因此在训练较为复杂的模型时,即模型训练过程中神经网络训练耗时远大于节点间通信耗时的场景下,推荐使用同步训练模式。

图2 同步训练模式示意图

  • 异步训练模式:如图3所示,在训练一个batch的数据后,Worker的每个线程会发送梯度给Server。而Server不会等待接收所有节点的梯度,而是直接基于已收到的梯度进行参数更新。异步训练去除了训练过程中的等待机制,训练速度得到了极大的提升,但是缺点也很明显,那就是Loss下降不稳定,容易发生抖动。建议在个性化推荐(召回、排序)、语义匹配等数据量大的场景使用。

    尤其是推荐领域的点击率预估场景,该场景可能会出现千亿甚至万亿规模的稀疏特征,而稀疏参数也可以达到万亿数量级,且需要小时级或分钟级流式增量训练。如果使用异步训练模式,可以很好的满足该场景的online-learning需求。

图3 异步训练模式示意图

  • GEO异步训练:GEO是飞桨自研的异步训练模式,如图4所示,其最大的特点是将参数的更新从Server转移到Worker上。每个Worker在本地训练过程中会使用SGD优化算法更新本地模型参数,在训练若干个batch的数据后,Worker将发送参数更新信息给Server。Server在接收后会通过加和方式更新保存的参数信息。所以显而易见,在GEO异步训练模式下,Worker不用再等待Server发来新的参数即可执行训练,在训练效果和训练速度上有了极大的提升。但是此模式比较适合可以在单机内能完整保存的模型,在搜索、NLP等类型的业务上应用广泛,推荐在词向量、语义匹配等场景中使用。

图4 异步训练模式示意图

经过上述介绍,我想小伙伴们应该对飞桨的参数服务器功能有了一定了解,可是这个参数服务器不仅包括了三种模式,还一会儿Worker一会儿Server的,用起来应该会很复杂吧?这个请放心,这个用起来其实非常简单,甚至比鸣人结手印召唤影分身还要简单!

十行代码单机转分布式

参数服务器模式

飞桨的分布式训练功能确实是比较复杂,其不仅包含参数服务器(同步、异步、GEO)模式,还包含collective、hybrid等其它模式。为了能让开发者们方便得使用这些功能,飞桨的工程师们非常贴心的专门为分布式训练设计了一套FleetAPI接口。如图5所示,使用FleetAPI可以轻松的将原先的单机训练转换为分布式参数服务器模式:

  1. 使用RoleMaker为参与训练的机器创建Worker和Server进程。RoleMaker有多种实现可适配用户的Kubernetes、MPI等环境。

  2. 使用Strategy和distributed_optimizer配置训练模式、优化函数以及计算图的拆分方案。在拆分计算图的过程中,Server和Worker中会被添加用于相互通信的算子。

  3. 初始化Worker和Server进程。

图5 FleetAPI功能示意图

具体操作方法请参见下面的代码示例。

如下为模型单机训练的代码,为了简化说明,这里省略了模型网络定义和数据读取等部分的代码。

exe = Executor(place)


optimizer = optimizer.Adam(learning_rate=0.001)
optimizer.minimize(avg_cost)
exe.run(default_startup_program())


for batch_id, data in enumerate(train_reader()):
avg_loss_value, auc_value = exe.run(main_program(), feed=feeder.feed(data))

用户只需要加入十行代码即可将上面的单机训练过程转换为分布式训练:

exe = Executor(place)
#设置节点角色
role = role_maker.PaddleCloudRoleMaker()
fleet.init(role)
optimizer = optimizer.Adam(learning_rate=0.001)
#配置策略
strategy = StrategyFactory.create_sync_strategy()
optimizer = fleet.distributed_optimizer(optimizer, strategy)
optimizer.minimize(avg_cost)
# 初始化并运行Server进程
if fleet.is_server():
   fleet.init_server()
   fleet.run_server()
# 初始化并运行Worker进程
if fleet.is_worker():
   fleet.init_worker()
exe.run(fleet.startup_program)
for batch_id, data in enumerate(train_reader()):
     avg_loss_value, auc_value = exe.run(fleet.main_program, feed=feeder.feed(data))
# 通知Server停止监听Worker请求
fleet.stop_worker()

性能远超业界同类最优产品!

在训练效果相同的情况下,飞桨的参数服务器训练模式在训练速度上有很大优势。相比于业界同类最优产品,参数服务器训练模式在相同机器数量和硬件配置条件下能够大幅提升模型训练速度。

如图6所示,在词向量Word2Vector模型上,采用GEO训练模式的飞桨分布式训练的训练速度能够超越同类最优产品 18倍

图6 Word2Vector模型性能示意图

在CTR-DNN模型上,如图7所示,采用全异步训练的训练模式也能够有6倍的速度提升。此外飞桨的推荐模型库还提供有包括DeepFM、Deep Cross Network、Gru4Rec等一系列经典个性化推荐类模型,方便开发者选择使用

图7 CTR-DNN模型性能示意图

相关工具组件简介

飞桨参数服务器功能在提供巨大性能优势的同时,也进一步支持了分布式训练相关的工具组件给用户使用。

  • 分布式指标功能:能够同步所有训练节点的AUC、准确率、正逆序等,统计出全局指标。

  • 分布式DEBUG功能:能够有序的将所有节点、所有线程、每层网络的参数和梯度打印到文件中,利于模型调试。

  • 流式训练功能:能够支持小时级流式、增量训练。

  • HDFS功能:封装了Python端的HDFS客户端,能够方便的在分布式训练中使用Hadoop存储功能。

业务应用示例

飞桨参数服务器模式如今已经在百度公司内外得到了普遍的应用,包括信息流、搜索等业务。下面以视频推荐场景为例介绍飞桨参数服务器的几种模式在业务中的具体应用。

图8 视频推荐系统示意图

如图8所以,视频推荐系统采用了漏斗模型,即召回->粗排->精排->融合的架构:

  • 召回:根据用户信息从几百万视频候选中抽取几万条结果;此处模型训练的特点是特征量小、训练数据少、模型算法简单,因此比较适合GEO模式和同步模式。

  • 粗排和精排:该过程是对召回的从几万条候选信息进行推理,推理出每条信息被点击到的概率并按照概率由大到小排序,然后抽取排位最高的几百条信息;此处模型训练的特点是特征量比较大、训练数据多、训练性能要求高,因此比较适合异步模式。

  • 融合:该过程是指从几百候选信息中抽取几十条;此处模型训练的特点是特征量小、训练性能要求高,但模型算法复杂,因此比较适合使用GEO模式。

经过实际业务验证,飞桨参数服务器功能可以轻松应对千万级用户数量、百亿特征规模的业务场景。

如果您加入官方QQ群,您将遇上大批志同道合的深度学习同学。官方QQ群:703252161

如果您想详细了解更多飞桨的相关内容,请参阅以下文档。

下载安装命令

## CPU版本安装命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle

## GPU版本安装命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu

官网地址:

https://www.paddlepaddle.org.cn

飞桨分布式训练项目地址:

https://github.com/PaddlePaddle/Fleet

飞桨个性化推荐模型项目地址:

https://github.com/PaddlePaddle/models/tree/develop/PaddleRec

飞桨开源框架项目地址:

GitHub:https://github.com/PaddlePaddle/Paddle

Gitee:  https://gitee.com/paddlepaddle/Paddle

本文同步分享在 博客“飞桨PaddlePaddle”(CSDN)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK