Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
FluidDoc
提交
e1a5bf55
F
FluidDoc
项目概览
PaddlePaddle
/
FluidDoc
通知
5
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看板
提交
e1a5bf55
编写于
11月 28, 2018
作者:
Y
Yancey1989
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
remove recordio example
上级
d6459d76
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
39 addition
and
93 deletion
+39
-93
doc/fluid/api/api_guides/index.rst
doc/fluid/api/api_guides/index.rst
+0
-1
doc/fluid/api/api_guides/low_level/cluster/cluster_train_data_cn.rst
...pi/api_guides/low_level/cluster/cluster_train_data_cn.rst
+39
-83
doc/fluid/api/api_guides/low_level/cluster/index.rst
doc/fluid/api/api_guides/low_level/cluster/index.rst
+0
-9
未找到文件。
doc/fluid/api/api_guides/index.rst
浏览文件 @
e1a5bf55
...
...
@@ -7,7 +7,6 @@ API使用指南
high_low_level_api.md
low_level/layers/index.rst
low_level/cluster/index.rst
low_level/executor.rst
low_level/optimizer.rst
low_level/metrics.rst
...
...
doc/fluid/api/api_guides/low_level/cluster/cluster_train_data_cn.rst
浏览文件 @
e1a5bf55
...
...
@@ -4,17 +4,33 @@
分布式训练数据准备
####################
一个数据并行的分布式训练任务通常会含有多个训练节点,每个训练节点负责训练整个数据集种的一部分。所以在
启动分布式训练任务之前需要将训练数据切分成多个小文件,通过一个 file_dispatcher 函数根据当前节点的
唯一序号(trainer_id)以及当前训练任务中训练节点的总数(trainers)决定读取哪一部分训练数据。
一个数据并行的分布式训练任务通常会含有多个训练进程,每个训练进程处理整个数据集中的一部分,根据当前进程的唯一序号(trainer_id)以及训练进程总数(trainers)可以决定当前训练进程应该读取哪一部分数据。
准备文本格式的
分布式训练数据集
------------------------------
实现 cluster_reader 来读取
分布式训练数据集
------------------------------
----------
训练数据切分
~~~~~~~~~~~~
比较通用的方法,可以实现一个 cluster_reader, 根据训练进程数量以及进程序号决定读取哪些 example:
简单的,对于文本类训练数据来说,我们可以使用 split 命令将训练数据切分成多个小文件,例如:
.. code-block:: python
def cluster_reader(reader, trainers, trainer_id):
def reader_creator():
for idx, data in enumerate(reader()):
if idx % trainers == trainer_id:
yield data
return reader
trainers = int(os.getenv("PADDLE_TRAINERS", "1"))
trainer_id = int(os.getenv("PADDLE_TRAINER_ID", "0"))
train_reader = cluster_reader(paddle.dataset.mnist.train(), trainers, trainer_id)
上述代码中,`trainers` 和 `trainer_id` 分别是训练进程总数和当前训练进程的序号,可以通过环境变量或者参数的方式传递给 Python 程序。
预先切分训练文件
-----------------
由于使用 `cluster_reader` 依然会读取全量数据,对于训练进程比较多的任务,会造成IO资源的浪费、影响训练性能。另一种方法是可以将训练数据切分成多个小文件,每个进程处理其中的一部分文件,
例如在 Linux 系统中可以使用 `split <http://man7.org/linux/man-pages/man1/split.1.html>`_ 命令将训练数据切分成多个小文件:
.. code-block:: bash
$ split -d -a 4 -d -l 100 housing.data cluster/housing.data.
...
...
@@ -27,82 +43,22 @@
cluster/housing.data.0001
cluster/housing.data.0005
读取分布式训练数据集
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
在数据并行场景下,我们需要将训练数据平均分配给每个训练节点,通常的方法是实现一个函数,使之能够
根据当前任务的训练节点数量以及当前节点的唯一序号决定需要读取哪些文件,例如:
.. code-block:: python
def file_dispatcher(file_pattern, trainers, trainer_id):
file_list = glob.glob(file_pattern)
ret_list = []
for idx, f in enumerate(file_list):
if (idx + trainers) % trainers == trainer_id:
ret_list.append(f)
return ret_list
- file_pattern: 训练数据文件目录目录,上述例子可以是 `cluster/housing.data.*`
- trainers: 当前任务的训练节点数。
- trainer_id: 当前训练节点的唯一序号。
准备 RecordIO 格式的分布式训练数据集
-------------------------------------
对于非文本类数据,可以预先将训练数据转换为 RecordIO 格式再进行训练, 并且转换成 RecordIO 格式
的另一个好处是可以提升 IO 效率,从而提升分布式训练任务的运行效率。
生成 RecordIO 格式数据集
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Fluid 提供了 `fluid.recordio_writer.convert_reader_to_recordio_files` API, 可以将训练数据转换成
RecordIO 格式, 样例代码如下
.. code-block:: python
reader = paddle.batch(mnist.train(), batch_size=1)
feeder = fluid.DataFeeder(
feed_list=[ # order is image and label
fluid.layers.data(
name='image', shape=[784]),
fluid.layers.data(
name='label', shape=[1], dtype='int64'),
],
place=fluid.CPUPlace())
fluid.recordio_writer.convert_reader_to_recordio_files(
filename_suffix='./mnist.recordio', batch_per_file=100, reader, feeder)
运行上述代码将会生成以下文件:
.. code-block:: bash
.
\_mnist-00000.recordio
|-mnist-00001.recordio
|-mnist-00002.recordio
|-mnist-00003.recordio
|-mnist-00004.recordio
API Reference 请参考::ref:`api_fluid_recordio_writer_convert_reader_to_recordio_file`
读取 RecordIO 训练数据
~~~~~~~~~~~~~~~~~~~~~~~~
数据切分好以后, 可以实现一个 file_dispatcher 函数,根据训练进程数量以及序号决定需要读取哪些文件:
Fluid 种提供了 `fluid.layers.io.open_files` API 来读取 RecordIO 格式的训练数据,在以下样例代码
中复用了上面例子中 `file_dispatcher` 函数来决定当前节点应该读取哪一部分训练数据:
.. code-block:: python
.. code-block:: python
def file_dispatcher(files_pattern, trainers, trainer_id):
file_list = glob.glob(files_pattern)
ret_list = []
for idx, f in enumerate(file_list):
if (idx + trainers) % trainers == trainer_id:
ret_list.append(f)
return ret_list
trainers = int(os.getenv("PADDLE_TRAINERS", "1"))
trainer_id = int(os.getenv("PADDLE_TRAINER_ID", "0"))
files_pattern = "cluster/housing.data.*"
trainers = int(os.getenv("PADDLE_TRAINERS"))
trainer_id = int(os.getenv("PADDLE_TRAINER_ID"))
data_file = fluid.layers.io.open_files(
filenames=file_dispatcher("./mnist-[0-9]*.recordio", 2, 0),
thread_num=1,
shapes=[(-1, 784),(-1, 1)],
lod_levels=[0, 0],
dtypes=["float32", "int32"])
img, label = fluid.layers.io.read_file(data_files)
my_files = file_dispatcher(files_pattern, triners, trainer_id)
API Reference 请参考: :ref:`api_fluid_layers_open_files`
在上述例子中,`files_pattern` 是训练文件的 glob 表达式,一般可以用通配符来表示。
\ No newline at end of file
doc/fluid/api/api_guides/low_level/cluster/index.rst
已删除
100644 → 0
浏览文件 @
d6459d76
==========
多机训练
==========
.. toctree::
:maxdepth: 1
cluster_train_data_cn.rst
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录