Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
FluidDoc
提交
5b0bec40
F
FluidDoc
项目概览
PaddlePaddle
/
FluidDoc
通知
8
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看板
未验证
提交
5b0bec40
编写于
9月 27, 2019
作者:
Z
Zeng Jinle
提交者:
GitHub
9月 27, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Refine memory_optimize_doc (#1432)
* refine memory_optimize_doc, test=develop * follow xiaoguang's comments, test=develop
上级
b8780798
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
68 addition
and
39 deletion
+68
-39
doc/fluid/advanced_usage/best_practice/memory_optimize.rst
doc/fluid/advanced_usage/best_practice/memory_optimize.rst
+68
-39
未找到文件。
doc/fluid/advanced_usage/best_practice/memory_optimize.rst
浏览文件 @
5b0bec40
.. _api_guide_memory_optimize:
###########
显存
分配与优化
存储
分配与优化
###########
PaddlePaddle的显存分配策略
========================
1.
PaddlePaddle的显存分配策略
========================
===
由于原生的CUDA系统调用 :code:`cudaMalloc` 和 :code:`cudaFree` 均是同步操作,非常耗时。因此与许多框架类似,PaddlePaddle采用了显存预分配的策略加速显存分配。具体方式为:
1.1. 显存预分配策略
----------------
由于原生的CUDA系统调用 :code:`cudaMalloc` 和 :code:`cudaFree` 均是同步操作,非常耗时。因此PaddlePaddle采用了显存预分配的策略加速显存分配。具体方式为:
- 在分配requested_size大小的显存时,
- 若requested_size <= chunk_size,则框架会预先分配chunk_size大小的显存池chunk,并从chunk中分出requested_size大小的块返回。之后每次申请显存都会从chunk中分配。
...
...
@@ -21,10 +24,9 @@ PaddlePaddle的显存分配策略
.. code-block:: python
chunk_size = FLAGS_fraction_of_gpu_memory_to_use * 单张GPU卡的总显存
chunk_size = FLAGS_fraction_of_gpu_memory_to_use * 单张GPU卡的当前可用显存值
:code:`FLAGS_fraction_of_gpu_memory_to_use` 的默认值为0.92,即框架预先分配显卡92%的
显存
。
:code:`FLAGS_fraction_of_gpu_memory_to_use` 的默认值为0.92,即框架预先分配显卡92%的
当前可用显存值
。
若你的GPU卡上有其他任务占用显存,你可以适当将 :code:`FLAGS_fraction_of_gpu_memory_to_use` 减少,保证框架能预分配到合适的chunk,例如:
...
...
@@ -35,49 +37,82 @@ PaddlePaddle的显存分配策略
若 :code:`FLAGS_fraction_of_gpu_memory_to_use` 设为0,则每次显存分配和释放均会调用 :code:`cudaMalloc` 和 :code:`cudaFree` ,会严重影响性能,不建议你使用。
只有当你想测量网络的实际显存占用量时,你可以设置 :code:`FLAGS_fraction_of_gpu_memory_to_use` 为0,观察nvidia-smi显示的显存占用情况。
PaddlePaddle的显存优化策略
========================
1.2. 显存自增长AutoGrowth策略
--------------------------
在1.6+的版本中,PaddlePaddle支持显存自增长AutoGrowth策略,按需分配显存。若您希望按需分配显存,您可选择使用显存自增长AutoGrowth策略。
在前几次显存分配时,会调用 :code:`cudaMalloc` 按需分配,但释放时不会调用 :code:`cudaFree` 返回给GPU,而是在框架内部缓存起来。
在随后的显存分配时,会首先检查缓存的显存中是否有合适的块,若有则从中分割出所需的显存空间返回,否则才调用 :code:`cudaMalloc` 直接从GPU中分配。随后的显存释放亦会缓存起来供后续分配使用。
因此,显存自增长AutoGrowth策略会在前几个batch训练时分配较慢(因为频繁调用 :code:`cudaMalloc` ),在随后训练过程中基本不会影响模型训练速度。
显存自增长AutoGrowth策略通过设置环境变量 :code:`FLAGS_allocator_strategy` 开启,设置方式为:
.. code-block:: shell
export FLAGS_allocator_strategy=auto_growth
对应地,显存预分配策略通过以下方法开启:
.. code-block:: shell
export FLAGS_allocator_strategy=naive_best_fit
环境变量 :code:`FLAGS_allocator_strategy` 的默认值为naive_best_fit,表示默认使用显存预分配策略。
PaddlePaddle提供了多种通用显存优化方法,优化你的网络的显存占用。
GC策略: 显存垃圾及时回收
====================
2. PaddlePaddle的存储优化策略
====================
=======
GC(Garbage Collection)的原理是在网络运行阶段及时释放无用变量的显存空间,达到节省显存的目的。GC适用于使用Executor,ParallelExecutor做模型训练/预测的场合。
PaddlePaddle提供了多种通用存储优化方法,优化你的网络的存储占用(包括显存和内存)。
2.1. GC策略: 存储垃圾及时回收
-------------------------
GC(Garbage Collection)的原理是在网络运行阶段及时释放无用变量的存储空间,达到节省存储空间的目的。GC适用于使用Executor,ParallelExecutor做模型训练/预测的场合,但不适用于C++预测库接口。
**GC策略已于1.6+版本中默认开启。**
GC策略由三个环境变量控制:
- :code:`FLAGS_eager_delete_tensor_gb`
GC策略的使能开关,double类型,
默认值为-1。GC策略会积攒一定大小的显存垃圾后再统一释放,:code:`FLAGS_eager_delete_tensor_gb` 控制的是显存
垃圾的阈值,单位是GB。**建议用户设置** :code:`FLAGS_eager_delete_tensor_gb=0` 。
GC策略的使能开关,double类型,
在<1.6的版本中默认值为-1,在1.6+版本中默认值为0。GC策略会积攒一定大小的存储垃圾后再统一释放,:code:`FLAGS_eager_delete_tensor_gb` 控制的是存储
垃圾的阈值,单位是GB。**建议用户设置** :code:`FLAGS_eager_delete_tensor_gb=0` 。
若 :code:`FLAGS_eager_delete_tensor_gb=0` ,则一旦有
显存垃圾则马上回收,最为节省显存
。
若 :code:`FLAGS_eager_delete_tensor_gb=0` ,则一旦有
存储垃圾则马上回收,最为节省存储空间
。
若 :code:`FLAGS_eager_delete_tensor_gb=1` ,则
显存
垃圾积攒到1G后才触发回收。
若 :code:`FLAGS_eager_delete_tensor_gb=1` ,则
存储
垃圾积攒到1G后才触发回收。
若 :code:`FLAGS_eager_delete_tensor_gb<0` ,则GC策略关闭。
- :code:`FLAGS_memory_fraction_of_eager_deletion`
GC策略的调节flag,double类型,默认值为1,范围为[0,1],仅适用于使用ParallelExecutor或CompiledProgram+with_data_parallel的场合。
GC内部会根据变量占用的显存大小,对变量进行降序排列,且仅回收前 :code:`FLAGS_memory_fraction_of_eager_deletion` 大的变量显存。**建议用户维持默认值**,即 :code:`FLAGS_memory_fraction_of_eager_deletion=1` 。
GC内部会根据变量占用的存储空间大小,对变量进行降序排列,且仅回收前 :code:`FLAGS_memory_fraction_of_eager_deletion` 大的变量的存储空间。**建议用户维持默认值**,即 :code:`FLAGS_memory_fraction_of_eager_deletion=1` 。
若 :code:`FLAGS_memory_fraction_of_eager_deletion=0.6` ,则表示仅回收存储占用60%大的变量的存储空间。
若 :code:`FLAGS_memory_fraction_of_eager_deletion=0
.6` ,则表示仅回收显存占用60%大的变量显存
。
若 :code:`FLAGS_memory_fraction_of_eager_deletion=0
` ,则表示不回收任何变量的存储空间,GC策略关闭
。
若 :code:`FLAGS_memory_fraction_of_eager_deletion=
0` ,则表示不回收任何变量的显存,GC策略关闭
。
若 :code:`FLAGS_memory_fraction_of_eager_deletion=
1` ,则表示回收所有变量的存储空间
。
若 :code:`FLAGS_memory_fraction_of_eager_deletion=1` ,则表示回收所有变量的显存。
- :code:`FLAGS_fast_eager_deletion_mode`
快速GC策略的开关,bool类型,默认值为True,表示使用快速GC策略。快速GC策略会不等待CUDA Kernel结束直接释放显存。**建议用户维持默认值**,即 :code:`FLAGS_fast_eager_deletion_mode=True` 。
Inplace策略: Op内部的输出复用输入
=============================
Inplace策略的原理是Op的输出复用Op输入的显存空间。例如,reshape操作的输出和输入可复用同一片显存空间。
2.2. Inplace策略: Op内部的输出复用输入
----------------------------------
Inplace策略的原理是Op的输出复用Op输入的存储空间。例如,reshape操作的输出和输入可复用同一片存储空间。
Inplace策略适用于使用ParallelExecutor或CompiledProgram+with_data_parallel的场合,通过 :code:`BuildStrategy` 设置。
Inplace策略适用于使用ParallelExecutor或CompiledProgram+with_data_parallel的场合,通过 :code:`BuildStrategy` 设置。此策略不支持使用Executor+Program做单卡训练、使用C++预测库接口等场合。
**Inplace策略已于1.6+版本中默认开启。**
具体方式为:
...
...
@@ -89,32 +124,26 @@ Inplace策略适用于使用ParallelExecutor或CompiledProgram+with_data_paralle
compiled_program = fluid.CompiledProgram(train_program)
.with_data_parallel(loss_name=loss.name, build_strategy=build_strategy)
由于目前设计上的一些问题,在开启Inplace策略后,必须保证后续exe.run中fetch_list的变量是persistable的,即假如你后续需要fetch的变量为loss和acc,则必须设置:
在<1.6的版本中,由于设计上的一些问题,在开启Inplace策略后,必须保证后续exe.run中fetch_list的变量是persistable的,即假如你后续需要fetch的变量为loss和acc,则必须设置:
.. code-block:: python
loss.persistable = True
acc.persistable = True
MemoryOptimize策略: 跨Op间的显存复用(不推荐)
========================================
MemoryOptimize策略的原理是当前Op的输出变量复用前继Op的无用变量空间。由于MemoryOptimize策略会延长显存空间的生命周期,这部分复用的显存可能无法及时释放,导致显存峰值升高,因此不建议用户使用该开关。
由于历史原因,PaddlePaddle提供了2个MemoryOptimize接口:
**在1.6+的版本中,无需设置fetch变量为persistable。**
- :code:`BuildStrategy` 中的 :code:`memory_optimize` :设置 :code:`build_strategy.memory_optimize=True` 开启MemoryOptimize策略。
- :code:`fluid.memory_optimize()` 接口:**该接口已废弃,不建议用户使用!**
3. 存储优化Best Practice
=======================
与Inplace策略相同,开启MemoryOptimize策略时同样要保证后续exe.run中fetch_list的变量是persistable的。
显存优化Best Practice
====================
我们推荐你的最佳显存优化策略为:
我们推荐你的最佳存储优化策略为:
- 开启GC策略:设置 :code:`FLAGS_eager_delete_tensor_gb=0` 。
- 开启Inplace策略:设置 :code:`build_strategy.enable_inplace = True` ,并设置fetch_list中的 :code:`var.persistable = True` 。
- 开启Inplace策略:设置 :code:`build_strategy.enable_inplace = True` ,并在<1.6版本中设置fetch_list中的 :code:`var.persistable = True` 。
**在1.6+的版本中,上述最佳策略均已默认打开,无需手动配置,亦无需设置fetch_list变量为persistable。**
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录