Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
FluidDoc
提交
b10bead3
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看板
未验证
提交
b10bead3
编写于
5月 14, 2020
作者:
L
lilong12
提交者:
GitHub
5月 14, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Modify the best practice guider for multi-node gpu training (#2094)
* modify the doc, test=develop
上级
2ece8ae0
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
34 addition
and
86 deletion
+34
-86
doc/fluid/advanced_guide/performance_improving/multinode_training_improving/dist_training_gpu.rst
...roving/multinode_training_improving/dist_training_gpu.rst
+34
-86
未找到文件。
doc/fluid/advanced_guide/performance_improving/multinode_training_improving/dist_training_gpu.rst
浏览文件 @
b10bead3
...
...
@@ -7,34 +7,39 @@
开始优化您的GPU分布式训练任务
---------------------------
PaddlePaddle Fluid可以支持在现代GPU [#]_ 服务器集群上完成高性能分布式训练。
通常可以通过以下方法优化在多机多卡环境训练性能,建议在进行性能优化时,
检查每项优化点并验证对应提升,从而提升最终的性能。
PaddlePaddle Fluid支持在现代GPU [#]_ 服务器集群上完成高性能分布式训练。通常可以通过以下方法优化在多机多卡环境训练性能,建议在进行性能优化时,检查每项优化点并验证对应提升,从而提升最终的性能。
一个简单的验证当前的训练程序是否需要进一步优化性能的方法,
是查看GPU的计算利用率 [#]_ ,通常用 :code:`nvidia-smi` 命令查看。
如果GPU利用率较低,则可能存在较大的优化空间。
下面主要从环境变量设置、训练策略设置、数据准备和训练方式四个方向介绍GPU分布式训练中常用的方法。
一个简单的验证当前的训练程序是否需要进一步优化性能的方法,是查看GPU的计算利用率 [#]_ ,通常用 :code:`nvidia-smi` 命令查看。如果GPU利用率较低,则可能存在较大的优化空间。下面主要从数据准备、训练策略设置和训练方式三个方面介绍GPU分布式训练中常用的优化方法。
1、
环境变量设置
===========
==
1、
数据准备
===========
环境变量设置表
数据读取的优化在GPU训练中至关重要,尤其在不断增加batch_size提升吞吐时,计算对reader性能会有更高对要求,优化reader性能需要考虑的点包括:
.. csv-table::
:header: "调节项", "可选值", "说明"
:widths: 3, 3, 5
- 使用 :code:`DataLoader` 。参考 `这里 <https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/api_cn/io_cn/DataLoader_cn.html#dataloader>`_ 使用DataLoader,并建议开启 :code:`use_double_buffer` 。
- reader返回uint8类型数据。图片在解码后一般会以uint8类型存储,如果在reader中转换成float类型数据,会将数据体积扩大4倍。直接返回uint8数据,然后在GPU上转化成float类型进行训练可以提升数据读取效率。
- 减少reader初始化时间 (infinite read)。在训练任务开始执行第一轮训练时,reader开始不断异步地从磁盘或其他存储中读取数据并执行预处理,然后将处理好的数据填充到队列中供计算使用。从0开始填充这个队列直到数据可以源源不断供给计算,需要一定时间的预热。所以,如果每轮训练都重新填充队列,会产生一些时间的开销。所以,在使用DataLoader时,可以让reader函数不断地产生数据,直到训练循环结束:
":code:`FLAGS_sync_nccl_allreduce`", "0,1", "是否同步AllReduce操作。1表示开启,每次调用等待AllReduce同步"
":code:`FLAGS_fraction_of_gpu_memory_to_use`", "0~1之间的float值", "预先分配显存的占比"
":code:`NCCL_IB_DISABLE` ", "0,1", "是否启用RDMA多机通信。如果机器硬件支持,可以设置1,开启RDMA支持"
.. code-block:: python
:linenos:
说明:
def infinite_reader(file_path):
while True:
with open(file_path) as fn:
for line in fn:
yield process(line)
def train():
...
for pass_id in xrange(NUM_PASSES):
if pass_id == 0:
data_loader.start()
for batch_id in (iters_per_pass):
exe.run()
data_loader.reset()
- 关于 :code:`FLAGS_sync_nccl_allreduce` ,配置 :code:`FLAGS_sync_nccl_allreduce=1` 让每次allreduce操作都等待完成,可以提升性能,详细原因和分析可以参考:https://github.com/PaddlePaddle/Paddle/issues/15049。
- 关于 :code:`FLAGS_fraction_of_gpu_memory_to_use` ,配置 :code:`FLAGS_fraction_of_gpu_memory_to_use=0.95` ,0.95是指95%的显存会预先分配。设置的范围是0.0~1.0。注意,设置成0.0会让每次显存分配都调用 :code:`cudaMalloc` 这样会极大的降低训练性能。
- 关于 :code:`NCCL_IB_DISABLE` ,在使用NCCL2模式训练时,其会默认尝试开启RDMA通信,如果系统不支持,则会自动降级为使用TCP通信。可以通过打开环境变量 :code:`NCCL_DEBUG=INFO` 查看NCCL是否选择了开启RDMA通信。如果需要强制使用TCP方式通信,可以设置 :code:`NCCL_IB_DISABLE=1` 。
另外,可以使用DALI库提升数据处理性能。DALI是NVIDIA开发的数据加载库,更多内容请参考 `官网文档 <https://docs.nvidia.com/deeplearning/dali/user-guide/docs/index.html>`_ 。飞桨中如何结合使用DALI库请参考 `使用示例 <https://github.com/PaddlePaddle/Fleet/tree/develop/benchmark/collective/resnet>`_ 。
2、训练策略设置
===========
...
...
@@ -48,9 +53,11 @@ PaddlePaddle Fluid可以支持在现代GPU [#]_ 服务器集群上完成高性
":code:`num_threads`", "int", "1", "CPU线程数"
":code:`nccl_comm_num`", "int", "1", "nccl通信器数量"
":code:`fuse_all_reduce_ops`", "bool", "False", "多卡训练时,将AllReduce操纵进行融合"
":code:`use_hierarchical_allreduce` ", "bool", "False","分级式reduce"
":code:`use_hierarchical_allreduce` ", "bool", "False",
"分级式reduce"
":code:`num_iteration_per_drop_scope`", "int", "1", "scope drop频率,设置每隔几个batch的迭代之后执行一次清理scope"
":code:`fetch_frequency`", "int", "1", "fetch的刷新频率"
":code:`fuse_bn_act_ops`", "bool", "False", "是否开启batch normalization和激活函数的融合"
":code:`fuse_elewise_add_act_ops`", "bool", "False", "是否开启elementwise add函数和激活函数的融合"
说明:
...
...
@@ -58,7 +65,7 @@ PaddlePaddle Fluid可以支持在现代GPU [#]_ 服务器集群上完成高性
- 关于AllReduce融合 :code:`fuse_all_reduce_ops` ,默认情况下会将同一layer中参数的梯度的AllReduce操作合并成一个,比如对于 :code:`fluid.layers.fc` 中有Weight和Bias两个参数,打开该选项之后,原本需要两次AllReduce操作,现在只用一次AllReduce 操作。此外,为支持更大粒度的参数梯度融合,Paddle提供了 :code:`FLAGS_fuse_parameter_memory_size` 和 :code:`FLAGS_fuse_parameter_groups_size` 两个环境变量选项。用户可以指定融合AllReduce操作之后,每个AllReduce操作的梯度字节数,比如希望每次AllReduce调用传输16MB的梯度,:code:`export FLAGS_fuse_parameter_memory_size=16` ,经验值为总通信量的十分之一。可以指定每次AllReduce操作的最大层数,即到达该层数就进行AllReduce,如指定50层 :code:`export FLAGS_fuse_parameter_groups_size=50` 。注意:目前不支持sparse参数梯度。
- 关于使用分级式reduce :code:`use_hierarchical_allreduce` 。对于多机模式,针对小数据量的通信,Ring AllReduce通信效率低,采用Hierarchical AllReduce可以解决该问题。
- 关于降低scope drop频率 :code:`num_iteration_per_drop_scope` 和fetch频率 :code:`fetch_frequency` 。减少scope drop和fetch频率,可以减少频繁的变量内存申请、释放和拷贝,从而提升性能。
-
其他训练策略的参数可以参考 `这里 <../best_practice/training_best_practice.html>`_
。
-
关于操作融合:通过参数融合可以提升训练性能
。
设置这些参数可以参考:
...
...
@@ -88,67 +95,12 @@ PaddlePaddle Fluid可以支持在现代GPU [#]_ 服务器集群上完成高性
exe.run([])
3、数据准备
===========
1、使用GPU完成部分图片预处理
如果可能,使用GPU完成部分数据预处理,比如图片Tensor的归一化:
.. code-block:: python
:linenos:
image = fluid.layers.data()
img_mean = fluid.layers.create_global_var([3, 1, 1], 0.0, "float32", name="img_mean", persistable=True)
img_std = fluid.layers.create_global_var([3, 1, 1], 0.0, "float32", name="img_std", persistable=True)
t1 = fluid.layers.elementwise_sub(image / 255.0, img_mean, axis=1)
image = fluid.layers.elementwise_div(t1, img_std, axis=1)
对输入的图片Tensor,使用 :code:`fluid.layers` 完成图片数据归一化预处理,
这样可以减轻CPU预处理数据的负担,提升总体训练速度。
2、优化reader性能
数据读取的优化在GPU训练中至关重要,尤其在不断增加batch_size提升吞吐时,计算对reader性能会有更高对要求,
优化reader性能需要考虑的点包括:
- 使用 :code:`pyreader` 。参考 `这里 <../../user_guides/howto/prepare_data/use_py_reader.html>`_ 使用pyreader,并开启 :code:`use_double_buffer` 。
- reader返回uint8类型数据。图片在解码后一般会以uint8类型存储,如果在reader中转换成float类型数据,会将数据体积扩大4倍。直接返回uint8数据,然后在GPU上转化成float类型进行训练
- 减少reader初始化时间 (infinite read)
在训练任务开始执行第一轮训练时,reader开始异步的,不断的从磁盘或其他存储中读取数据并执行预处理,然后将处理好的数据
填充到队列中供计算使用。从0开始填充这个队列直到数据可以源源不断供给计算,需要一定时间的预热。所以,如果每轮训练
都重新填充队列,会产生一些时间的开销。所以,在使用pyreader时,可以让reader函数不断的产生数据,直到训练循环手动break:
.. code-block:: python
:linenos:
def infinite_reader(file_path):
while True:
with open(file_path) as fn:
for line in fn:
yield process(line)
def train():
...
for pass_id in xrange(NUM_PASSES):
if pass_id == 0:
pyreader.start()
for batch_id in (iters_per_pass):
exe.run()
pyreader.reset()
4、训练方式
3、训练方式
===========
1、Local SGD
GPU多机多卡同步训练过程中存在慢trainer现象,
即每步中训练快的trainer的同步通信需要等待训练慢的trainer。
由于每步中慢trainer的rank具有随机性,
因此我们使用局部异步训练的方式——LocalSGD,
通过多步异步训练(无通信阻塞)实现慢trainer时间均摊,
从而提升同步训练性能。
Local SGD训练方式主要有三个参数,分别是:
GPU多机多卡同步训练过程中存在慢trainer现象,即每步中训练快的trainer的同步通信需要等待训练慢的trainer。由于每步中慢trainer的rank具有随机性,因此我们使用局部异步训练的方式——LocalSGD,通过多步异步训练(无通信阻塞)实现慢trainer时间均摊,从而提升同步训练性能。Local SGD训练方式主要有三个参数,分别是:
.. csv-table::
:header: "选项", "类型", "可选值", "说明"
...
...
@@ -163,18 +115,14 @@ Local SGD训练方式主要有三个参数,分别是:
- Local SGD的warmup步长 :code:`local_sgd_is_warm_steps` 影响最终模型的泛化能力,一般需要等到模型参数稳定之后在进行Local SGD训练,经验值可以将学习率第一次下降时的epoch作为warmup步长,之后再进行Local SGD训练。
- Local SGD步长 :code:`local_sgd_steps` ,一般该值越大,通信次数越少,训练速度越快,但随之而来的时模型精度下降。经验值设置为2或者4。
具体的Local SGD的训练代码可以参考:
https://github.com/PaddlePaddle/Fleet/tree/develop/examples/local_sgd/resnet
具体的Local SGD的训练代码可以参考:https://github.com/PaddlePaddle/Fleet/tree/develop/examples/local_sgd/resnet
2、使用混合精度训练
V100 GPU提供了 `Tensor Core <https://www.nvidia.com/en-us/data-center/tensorcore/>`_ 可以在混合精度计算
场景极大的提升性能。使用混合精度计算的例子可以参考:
https://github.com/PaddlePaddle/models/tree/develop/PaddleCV/image_classification#using-mixed-precision-training
V100 GPU提供了 `Tensor Core <https://www.nvidia.com/en-us/data-center/tensorcore/>`_ 可以在混合精度计算场景极大的提升性能。使用混合精度计算的例子可以参考:https://github.com/PaddlePaddle/models/tree/develop/PaddleCV/image_classification#using-mixed-precision-training
目前Paddle只提供在两个模型(ResNet, BERT)的混合精度计算实现并支持static loss scaling,其他模型使用混合精度也
可以参考以上的实现完成验证。
目前Paddle只提供在两个模型(ResNet, BERT)的混合精度计算实现并支持static loss scaling,其他模型使用混合精度也可以参考以上的实现完成验证。
附录
----
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录