Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
FluidDoc
提交
f84af2fa
F
FluidDoc
项目概览
PaddlePaddle
/
FluidDoc
通知
10
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
23
列表
看板
标记
里程碑
合并请求
111
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
F
FluidDoc
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
23
Issue
23
列表
看板
标记
里程碑
合并请求
111
合并请求
111
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
f84af2fa
编写于
8月 01, 2019
作者:
D
Dong Daxiang
提交者:
GitHub
8月 01, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Update cluster_quick_start.rst (#1060)
* Update cluster_quick_start.rst
上级
9f18368d
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
132 addition
and
192 deletion
+132
-192
doc/fluid/user_guides/howto/training/cluster_quick_start.rst
doc/fluid/user_guides/howto/training/cluster_quick_start.rst
+132
-192
未找到文件。
doc/fluid/user_guides/howto/training/cluster_quick_start.rst
浏览文件 @
f84af2fa
...
@@ -3,195 +3,135 @@
...
@@ -3,195 +3,135 @@
分布式训练快速开始
分布式训练快速开始
==================
==================
准备工作
使用Fleet API进行分布式训练
--------
---------------------------
在本篇文章中,我们将会在介绍如何快速在一个集群中启动一个 PaddlePaddle
从Paddle Fluid `Release 1.5.1 <https://github.com/PaddlePaddle/Paddle/releases/tag/v1.5.1>`_ 开始,官方推荐使用Fleet API进行分布式训练,关于Fleet API的介绍可以参考 `Fleet Design Doc <https://github.com/PaddlePaddle/Fleet>`_
的分布式训练任务,在开始之前,请按如下步骤做些准备工作:
1. 准备一个网络连通的训练集群,在本文中我们使用4个训练节点使用 ``*.paddlepaddle.com``
准备条件
来表示节点的主机名称,您可以根据实际情况修改它。
^^^^^^^^
2. 在开始之前确保已经阅读过 :ref:`install_steps`
并且可以在集群的所有节点上可以正常运行 PaddlePaddle。
*
[x] 成功安装Paddle Fluid,如果尚未安装,请参考 `快速开始 <https://www.paddlepaddle.org.cn/documentation/docs/zh/1.5/beginners_guide/quick_start_cn.html>`_
样例代码
-------
*
[x] 学会最基本的单机训练方法,请参考 `单机训练 <https://www.paddlepaddle.org.cn/documentation/docs/zh/1.5/user_guides/howto/training/single_node.html>`_ 中描述的单卡训练,进行学习
下面使用一个非常简单的线性回归模型作为样例来解释如何启动一个包含2个 ``PSERVER`` 节点以及
2个 ``TRAINER`` 节点的分布式训练任务,您可以将本段代码保存为 ``dist_train.py`` 运行。
点击率预估任务
^^^^^^^^^^^^^^
.. code:: python
本文使用一个简单的示例,点击率预估任务,来说明如何使用Fleet API进行分布式训练的配置方法,并利用单机环境模拟分布式环境给出运行示例。示例的源码来自 `CTR with Fleet <https://github.com/PaddlePaddle/Fleet/tree/develop/examples/ctr>`_
import os
import paddle
import paddle.fluid as fluid
为了方便学习,这里给出的示例是单机与多机混合的代码,用户可以通过不同的启动命令进行单机或多机任务的启动。获取数据的部分,以及对数据预处理的逻辑可以参考 `CTR with Fleet <https://github.com/PaddlePaddle/Fleet/tree/develop/examples/ctr>`_ 的源码和说明,这里不做过多描述。
# train reader
.. code-block:: python
BATCH_SIZE = 20
EPOCH_NUM = 30
from __future__ import print_function
BATCH_SIZE = 8
from args import parse_args
import os
train_reader = paddle.batch(
import paddle.fluid as fluid
paddle.reader.shuffle(
import sys
paddle.dataset.uci_housing.train(), buf_size=500),
from network_conf import ctr_dnn_model_dataset
batch_size=BATCH_SIZE)
import paddle.fluid.incubate.fleet.base.role_maker as role_maker
def train():
from paddle.fluid.incubate.fleet.parameter_server.distribute_transpiler import fleet
y = fluid.layers.data(name='y', shape=[1], dtype='float32')
from paddle.fluid.transpiler.distribute_transpiler import DistributeTranspilerConfig
x = fluid.layers.data(name='x', shape=[13], dtype='float32')
y_predict = fluid.layers.fc(input=x, size=1, act=None)
dense_feature_dim = 13
sparse_feature_dim = 10000001
loss = fluid.layers.square_error_cost(input=y_predict, label=y)
batch_size = 100
avg_loss = fluid.layers.mean(loss)
thread_num = 10
opt = fluid.optimizer.SGD(learning_rate=0.001)
embedding_size = 10
opt.minimize(avg_loss)
args = parse_args()
place = fluid.CPUPlace()
def main_function(is_local):
feeder = fluid.DataFeeder(place=place, feed_list=[x, y])
# common code for local training and distributed training
exe = fluid.Executor(place)
dense_input = fluid.layers.data(
name="dense_input", shape=[dense_feature_dim], dtype='float32')
# fetch distributed training environment setting
training_role = os.getenv("PADDLE_TRAINING_ROLE", None)
sparse_input_ids = [
port = os.getenv("PADDLE_PSERVER_PORT", "6174")
fluid.layers.data(name="C" + str(i), shape=[1], lod_level=1,
pserver_ips = os.getenv("PADDLE_PSERVER_IPS", "")
dtype="int64") for i in range(1, 27)]
trainer_id = int(os.getenv("PADDLE_TRAINER_ID", "0"))
eplist = []
label = fluid.layers.data(name="label", shape=[1], dtype="int64")
for ip in pserver_ips.split(","):
dataset = fluid.DatasetFactory().create_dataset()
eplist.append(':'.join([ip, port]))
dataset.set_use_var([dense_input] + sparse_input_ids + [label])
pserver_endpoints = ",".join(eplist)
pipe_command = "python criteo_reader.py %d" % sparse_feature_dim
trainers = int(os.getenv("PADDLE_TRAINERS"))
dataset.set_pipe_command(pipe_command)
current_endpoint = os.getenv("PADDLE_CURRENT_IP", "") + ":" + port
dataset.set_batch_size(batch_size)
dataset.set_thread(thread_num)
t = fluid.DistributeTranspiler()
t.transpile(
whole_filelist = ["raw_data/part-%d" % x
trainer_id = trainer_id,
for x in range(len(os.listdir("raw_data")))]
pservers = pserver_endpoints,
trainers = trainers)
dataset.set_filelist(whole_filelist)
loss, auc_var, batch_auc_var = ctr_dnn_model_dataset(
if training_role == "PSERVER":
dense_input, sparse_input_ids, label, embedding_size,
pserver_prog = t.get_pserver_program(current_endpoint)
sparse_feature_dim)
startup_prog = t.get_startup_program(current_endpoint, pserver_prog)
exe.run(startup_prog)
exe = fluid.Executor(fluid.CPUPlace())
exe.run(pserver_prog)
def train_loop(epoch=20):
elif training_role == "TRAINER":
for i in range(epoch):
trainer_prog = t.get_trainer_program()
exe.train_from_dataset(program=fluid.default_main_program(),
exe.run(fluid.default_startup_program())
dataset=dataset,
fetch_list=[auc_var],
for epoch in range(EPOCH_NUM):
fetch_info=["auc"],
for batch_id, batch_data in enumerate(train_reader()):
debug=False)
avg_loss_value, = exe.run(trainer_prog,
# local training
feed=feeder.feed(batch_data),
def local_train():
fetch_list=[avg_loss])
optimizer = fluid.optimizer.SGD(learning_rate=1e-4)
if (batch_id + 1) % 10 == 0:
optimizer.minimize(loss)
print("Epoch: {0}, Batch: {1}, loss: {2}".format(
exe.run(fluid.default_startup_program())
epoch, batch_id, avg_loss_value[0]))
train_loop()
# destory the resource of current trainer node in pserver server node
exe.close()
# distributed training
else:
def dist_train():
raise AssertionError("PADDLE_TRAINING_ROLE should be one of [TRAINER, PSERVER]")
role = role_maker.PaddleCloudRoleMaker()
fleet.init(role)
train()
strategy = DistributeTranspilerConfig()
strategy.sync_mode = False
环境变量说明
optimizer = fluid.optimizer.SGD(learning_rate=1e-4)
-----------
optimizer = fleet.distributed_optimizer(optimizer, strategy)
optimizer.minimize(loss)
在启动分布式训练任务时,使用不同的环境变量来表示不同的节点角色,具体如下:
if fleet.is_server():
.. list-table::
fleet.init_server()
:header-rows: 1
fleet.run_server()
elif fleet.is_worker():
* - 环境变量
fleet.init_worker()
- 数据类型
exe.run(fluid.default_startup_program())
- 样例
train_loop()
- 描述
if is_local:
* - :code:`PADDLE_TRAINING_ROLE`
local_train()
- str
else:
- :code:`PSERVER,TRAINER`
dist_train()
- 当前训练节点角色
* - :code:`PADDLE_PSERVER_IPS`
if __name__ == '__main__':
- str
main_function(args.is_local)
- :code:`ps0.paddlepaddle.com,ps1.paddlepaddle.com`
- 分布式训练任务中所有 PSERVER 节点的 IP 地址或 hostname, 使用","分隔
* - :code:`PADDLE_PSERVER_PORT`
* 说明:示例中使用的IO方法是dataset,想了解具体的文档和用法请参考 `Dataset API <hhttps://www.paddlepaddle.org.cn/documentation/docs/zh/1.5/api_cn/dataset_cn.html>`_ 。示例中使用的 ``train_from_dataset`` 接口,想了解具体的文档和使用方法请参考 `Executor API <https://www.paddlepaddle.org.cn/documentation/docs/zh/1.5/api_cn/executor_cn.html>`_ 。示例中的 ``from paddle.fluid.incubate.fleet.parameter_server.distribute_transpiler import fleet`` 表示引入参数服务器架构进行分布式训练,如果想更进一步了解Fleet API的更多选项和示例,请参考 `Fleet API <https://www.paddlepaddle.org.cn/documentation/docs/zh/1.5/user_guides/howto/training/fleet_api_howto_cn.html>`_
- int
- 6174
- PSERVER 进程监听的端口
单机训练启动命令
* - :code:`PADDLE_TRAINERS`
~~~~~~~~~~~~~~~~
- int
- 2
.. code-block:: bash
- 分布式训练任务中 trainer 节点的数量
* - :code:`PADDLE_CURRENT_IP`
python train.py --is_local 1
- str
- :code:`ps0.paddlepaddle.com`
单机模拟分布式训练的启动命令
- 当前 PSERVER 节点的 IP 地址或 hostname
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* - :code:`PADDLE_TRAINER_ID`
- str
在单机模拟多机训练的启动命令,这里我们用到了paddle内置的一个启动器launch_ps,用户可以指定worker和server的数量进行参数服务器任务的启动
- 0
- 当前 TRAINER 节点的 ID (唯一), 取值范围为 [0, PADDLE_TRAINERS)
.. code-block:: bash
注: 环境变量只是获取运行时信息的一种方式,实际任务中可以采用命令行参数等方式获取运行时信息。
python -m paddle.distributed.launch_ps --worker_num 2 --server_num 2 train.py
分布式训练相关 API
任务运行的日志在工作目录的logs目录下可以查看,当您能够使用单机模拟分布式训练,可以进行真正的多机分布式训练。我们建议用户直接参考 `百度云运行分布式任务的示例 <https://www.paddlepaddle.org.cn/documentation/docs/zh/1.5/user_guides/howto/training/deploy_ctr_on_baidu_cloud_cn.html>`_
------------------
DistributeTranspiler
~~~~~~~~~~~~~~~~~~~~~~
基于 pserver-trainer 架构的的分布式训练任务分为两种角色: Parameter Server(PSERVER) 以及 TRAINER,
在 Fluid 中,用户只需配置单机训练所需要的网络配置, ``DistributeTranspiler`` 模块会自动地根据
当前训练节点的角色将用户配置的单机网路配置改写成 PSERVER 和 TRAINER 需要运行的网络配置:
.. code:: python
t = fluid.DistributeTranspiler()
t.transpile(
trainer_id = trainer_id,
pservers = pserver_endpoints,
trainers = trainers)
if PADDLE_TRAINING_ROLE == "TRAINER":
# fetch the trainer program and execute it
trainer_prog = t.get_trainer_program()
...
elif PADDLE_TRAINER_ROLE == "PSERVER":
# fetch the pserver program and execute it
pserver_prog = t.get_pserver_program(current_endpoint)
...
exe.close()
~~~~~~~~~~~~~~
PSERVER 节点中会保存所有 TRAINER 节点的状态信息,在 TRAINER 结束训练时需要调用 ``exe.close()``
通知所有 PSERVER 节点释放当前 TRAINER 节点的资源:
.. code:: python
exe = fluid.Executor(fluid.CPUPlace())
# training process ...
exe.close() # notify PServer to destory the resource
注意:所有的trainer在退出时都需要调用exe.close()。
启动分布式训练任务
--------------------
.. list-table::
:header-rows: 1
* - 启动节点
- 启动命令
- 说明
* - ps0.paddlepaddle.com
- :code:`PADDLE_TRAINING_ROLE=PSERVER PADDLE_CURRENT_IP=ps0.paddlepaddle.com PADDLE_PSERVER_IPS=ps0.paddlepaddle.com,ps1.paddlepaddle.com PADDLE_TRAINERS=2 PADDLE_PSERVER_PORT=6174 python fluid_dist.py`
- 启动 PSERVER 节点
* - ps1.paddlepaddle.com
- :code:`PADDLE_TRAINING_ROLE=PSERVER PADDLE_CURRENT_IP=ps1.paddlepaddle.com PADDLE_PSERVER_IPS=ps0.paddlepaddle.com,ps1.paddlepaddle.com PADDLE_TRAINERS=2 PADDLE_PSERVER_PORT=6174 python fluid_dist.py`
- 启动 PSERVER 节点
* - trainer0.paddlepaddle.com
- :code:`PADDLE_TRAINING_ROLE=TRAINER PADDLE_PSERVER_IPS=ps0.paddlepaddle.com,ps1.paddlepaddle.com PADDLE_TRAINERS=2 PADDLE_TRAINER_ID=0 PADDLE_PSERVER_PORT=6174 python fluid_dist.py`
- 启动第0号 TRAINER 节点
* - trainer1.paddlepaddle.com
- :code:`PADDLE_TRAINING_ROLE=TRAINER PADDLE_PSERVER_IPS=ps0.paddlepaddle.com,ps1.paddlepaddle.com PADDLE_TRAINERS=2 PADDLE_TRAINER_ID=1 PADDLE_PSERVER_PORT=6174 python fluid_dist.py`
- 启动第1号 TRAINER 节点
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录