未验证 提交 76a06604 编写于 作者: Z Zeng Jinle 提交者: GitHub

fix 1.7 doc, test=develop (#1833)

上级 946e0a73
......@@ -56,12 +56,20 @@ blocks中包含:
block的概念与通用程序一致,例如在下列这段C++代码中包含三个block:
``` cpp
int main(){ //block 0
int i = 0;
if (i<10){ //block 1
for (int j=0;j<10;j++){ //block 2
}
#include <iostream>
int main() {
int x = 5; // block 0
int y = 4; // block 0
int out; // block 0
if (x < y) { // block 0
out = 1; // block 1
} else {
out = 0; // block 2
}
std::cout << out << std::endl;
return 0;
}
```
......@@ -69,27 +77,20 @@ int main(){ //block 0
类似的,在下列 Paddle 的 Program 包含3段block:
```python
import paddle.fluid as fluid # block 0
limit = fluid.layers.fill_constant_batch_size_like(
input=label, dtype='int64', shape=[1], value=5.0)
cond = fluid.layers.less_than(x=label, y=limit)
ie = fluid.layers.IfElse(cond)
with ie.true_block(): # block 1
true_image = ie.input(image)
hidden = fluid.layers.fc(input=true_image, size=100, act='tanh')
prob = fluid.layers.fc(input=hidden, size=10, act='softmax')
ie.output(prob)
with ie.false_block(): # block 2
false_image = ie.input(image)
hidden = fluid.layers.fc(
input=false_image, size=200, act='tanh')
prob = fluid.layers.fc(input=hidden, size=10, act='softmax')
ie.output(prob)
prob = ie()
import paddle.fluid as fluid
x = fluid.data(name='x', shape=[1], dtype='int64') # block 0
y = fluid.data(name='y', shape=[1], dtype='int64') # block 0
def true_block():
return fluid.layers.fill_constant(dtype='int64', value=1, shape=[1]) # block 1
def false_block():
return fluid.layers.fill_constant(dtype='int64', value=0, shape=[1]) # block 2
condition = fluid.layers.less_than(x, y) # block 0
out = fluid.layers.cond(condition, true_block, false_block) # block 0
```
### BlockDesc and ProgramDesc
......
......@@ -7,20 +7,26 @@
1. PaddlePaddle的显存分配策略
===========================
1.1. 显存预分配策略
----------------
1.1. 显存自增长AutoGrowth策略
--------------------------
自1.6+的版本起,PaddlePaddle支持显存自增长AutoGrowth策略,按需分配显存,且已于1.7+版本中默认开启,方便用户在同一张GPU卡上同时运行多个任务。
由于原生的CUDA系统调用 :code:`cudaMalloc` 和 :code:`cudaFree` 均是同步操作,非常耗时。因此PaddlePaddle采用了显存预分配的策略加速显存分配。具体方式为:
由于原生的CUDA系统调用 :code:`cudaMalloc` 和 :code:`cudaFree` 均是同步操作,非常耗时。
因此显存自增长AutoGrowth策略会缓存已分配到的显存,供后续分配使用,具体方式为:
- 在分配requested_size大小的显存时,
- 若requested_size <= chunk_size,则框架会预先分配chunk_size大小的显存池chunk,并从chunk中分出requested_size大小的块返回。之后每次申请显存都会从chunk中分配。
- 若requested_size > chunk_size,则框架会直接调用 :code:`cudaMalloc` 分配requested_size大小的显存返回。
- 在前几次显存分配时,框架会调用 :code:`cudaMalloc` 按需分配,但释放时不会调用 :code:`cudaFree` 返回给GPU,而是在框架内部缓存起来。
- 在释放free_size大小的显存时,
- 若free_size <= chunk_size,则框架会将该显存放回预分配的chunk中,而不是直接返回给CUDA。
- 若free_size > chunk_size,则框架会直接调用 :code:`cudaFree` 将显存返回给CUDA
- 在随后的显存分配时,框架会首先检查缓存的显存中是否有合适的块,若有则从中分割出所需的显存空间返回,否则才调用 :code:`cudaMalloc` 直接从GPU中分配。随后的显存释放亦会缓存起来供后续分配使用。
因此,显存自增长AutoGrowth策略会在前几个batch训练时分配较慢(因为频繁调用 :code:`cudaMalloc` ),在随后训练过程中基本不会影响模型训练速度
上述的chunk_size由环境变量 :code:`FLAGS_fraction_of_gpu_memory_to_use` 确定,chunk_size的计算公式为:
1.2. 显存预分配策略
----------------
除了显存自增长AutoGrowth策略以外,PaddlePaddle还提供了显存预分配策略。显存预分配策略是PaddlePaddle 1.7版本前的默认显存分配策略。
显存预分配策略会在第一次分配时分配很大chunk_size的显存块,随后的显存分配大多从预分配的显存块中切分获得。
其中,chunk_size由环境变量 :code:`FLAGS_fraction_of_gpu_memory_to_use` 确定,chunk_size的计算公式为:
.. code-block:: python
......@@ -28,7 +34,17 @@
:code:`FLAGS_fraction_of_gpu_memory_to_use` 的默认值为0.92,即框架预先分配显卡92%的当前可用显存值。
若你的GPU卡上有其他任务占用显存,你可以适当将 :code:`FLAGS_fraction_of_gpu_memory_to_use` 减少,保证框架能预分配到合适的chunk,例如:
显存预分配策略分配显存的具体方式为:
- 在分配requested_size大小的显存时,
- 若requested_size <= chunk_size,则框架会预先分配chunk_size大小的显存池chunk,并从chunk中分出requested_size大小的块返回。之后每次申请显存都会从chunk中分配。
- 若requested_size > chunk_size,则框架会直接调用 :code:`cudaMalloc` 分配requested_size大小的显存返回。
- 在释放free_size大小的显存时,
- 若free_size <= chunk_size,则框架会将该显存放回预分配的chunk中,而不是直接返回给CUDA。
- 若free_size > chunk_size,则框架会直接调用 :code:`cudaFree` 将显存返回给CUDA。
若你的GPU卡上有其他任务占用显存,你可以适当将 :code:`FLAGS_fraction_of_gpu_memory_to_use` 减少,保证框架能预分配到合适的显存块,例如:
.. code-block:: shell
......@@ -37,29 +53,21 @@
若 :code:`FLAGS_fraction_of_gpu_memory_to_use` 设为0,则每次显存分配和释放均会调用 :code:`cudaMalloc` 和 :code:`cudaFree` ,会严重影响性能,不建议你使用。
只有当你想测量网络的实际显存占用量时,你可以设置 :code:`FLAGS_fraction_of_gpu_memory_to_use` 为0,观察nvidia-smi显示的显存占用情况。
1.2. 显存自增长AutoGrowth策略
--------------------------
在1.6+的版本中,PaddlePaddle支持显存自增长AutoGrowth策略,按需分配显存。若您希望按需分配显存,您可选择使用显存自增长AutoGrowth策略。
在前几次显存分配时,会调用 :code:`cudaMalloc` 按需分配,但释放时不会调用 :code:`cudaFree` 返回给GPU,而是在框架内部缓存起来。
1.3. 显存分配策略的选择方式
-----------------------
自1.6+版本起,PaddlePaddle同时支持显存自增长AutoGrowth策略和显存预分配策略,并通过环境变量 :code:`FLAGS_allocator_strategy` 控制。
在随后的显存分配时,会首先检查缓存的显存中是否有合适的块,若有则从中分割出所需的显存空间返回,否则才调用 :code:`cudaMalloc` 直接从GPU中分配。随后的显存释放亦会缓存起来供后续分配使用。
因此,显存自增长AutoGrowth策略会在前几个batch训练时分配较慢(因为频繁调用 :code:`cudaMalloc` ),在随后训练过程中基本不会影响模型训练速度。
显存自增长AutoGrowth策略通过设置环境变量 :code:`FLAGS_allocator_strategy` 开启,设置方式为:
选择显存自增长AutoGrowth的方式为:
.. code-block:: shell
export FLAGS_allocator_strategy=auto_growth
export FLAGS_allocator_strategy=auto_growth # 选择显存自增长AutoGrowth策略
对应地,显存预分配策略通过以下方法开启
选择显存预分配策略的方式为
.. code-block:: shell
export FLAGS_allocator_strategy=naive_best_fit
环境变量 :code:`FLAGS_allocator_strategy` 的默认值为naive_best_fit,表示默认使用显存预分配策略。
export FLAGS_allocator_strategy=naive_best_fit # 选择显存预分配策略
2. PaddlePaddle的存储优化策略
......
.. THIS FILE IS GENERATED BY `gen_doc.{py|sh}`
!DO NOT EDIT THIS FILE MANUALLY!
.. _api_fluid_recordio_writer_convert_reader_to_recordio_file:
convert_reader_to_recordio_file
-------------------------------
.. autofunction:: paddle.fluid.recordio_writer.convert_reader_to_recordio_file
:noindex:
.. THIS FILE IS GENERATED BY `gen_doc.{py|sh}`
!DO NOT EDIT THIS FILE MANUALLY!
.. _api_fluid_recordio_writer_convert_reader_to_recordio_files:
convert_reader_to_recordio_files
--------------------------------
.. autofunction:: paddle.fluid.recordio_writer.convert_reader_to_recordio_files
:noindex:
......@@ -17,8 +17,8 @@
import paddle.fluid as fluid
image = fluid.layers.data(name="image", shape=[784])
label = fluid.layers.data(name="label", shape=[1])
image = fluid.data(name="image", shape=[None, 784], dtype='float32')
label = fluid.data(name="label", shape=[None, 1], dtype='int64')
hidden = fluid.layers.fc(input=image, size=100, act='relu')
prediction = fluid.layers.fc(input=hidden, size=10, act='softmax')
loss = fluid.layers.cross_entropy(input=prediction, label=label)
......@@ -70,7 +70,7 @@
train_program = fluid.Program()
startup_program = fluid.Program()
with fluid.program_guard(train_program, startup_program):
data = fluid.layers.data(name='X', shape=[1], dtype='float32')
data = fluid.data(name='X', shape=[None, 1], dtype='float32')
hidden = fluid.layers.fc(input=data, size=10)
loss = fluid.layers.mean(hidden)
sgd = fluid.optimizer.SGD(learning_rate=0.001)
......@@ -92,14 +92,14 @@
fetch_list=[loss.name])
# Or use CompiledProgram:
compiled_prog = compiler.CompiledProgram(train_program)
compiled_prog = fluid.CompiledProgram(train_program)
loss_data, = exe.run(compiled_prog,
feed={"X": x},
fetch_list=[loss.name])
多卡训练
#######################
在多卡训练中,你可以使用 :code:`fluid.compiler.CompiledProgram` 来编译 :code:`fluid.Program` ,然后调用 :code:`with_data_parallel` 。例如:
在多卡训练中,你可以使用 :code:`fluid.CompiledProgram` 来编译 :code:`fluid.Program` ,然后调用 :code:`with_data_parallel` 。例如:
.. code-block:: python
......@@ -112,7 +112,7 @@
if not use_cuda:
os.environ['CPU_NUM'] = str(2)
compiled_prog = compiler.CompiledProgram(
compiled_prog = fluid.CompiledProgram(
train_program).with_data_parallel(
loss_name=loss.name)
loss_data, = exe.run(compiled_prog,
......@@ -129,3 +129,8 @@
进阶使用
###############
.. toctree::
:maxdepth: 2
test_while_training.rst
......@@ -13,8 +13,8 @@ For example:
import paddle.fluid as fluid
image = fluid.layers.data(name="image", shape=[784])
label = fluid.layers.data(name="label", shape=[1])
image = fluid.data(name="image", shape=[None, 784], dtype='float32')
label = fluid.data(name="label", shape=[None, 1], dtype='int64')
hidden = fluid.layers.fc(input=image, size=100, act='relu')
prediction = fluid.layers.fc(input=hidden, size=10, act='softmax')
loss = fluid.layers.cross_entropy(input=prediction, label=label)
......@@ -61,7 +61,7 @@ In the runtime, feed data with :code:`run(feed=...)` and get persistable data wi
train_program = fluid.Program()
startup_program = fluid.Program()
with fluid.program_guard(train_program, startup_program):
data = fluid.layers.data(name='X', shape=[1], dtype='float32')
data = fluid.data(name='X', shape=[None, 1], dtype='float32')
hidden = fluid.layers.fc(input=data, size=10)
loss = fluid.layers.mean(hidden)
sgd = fluid.optimizer.SGD(learning_rate=0.001)
......@@ -82,7 +82,7 @@ In the runtime, feed data with :code:`run(feed=...)` and get persistable data wi
feed={"X": x},
fetch_list=[loss.name])
# Or
# compiled_prog = compiler.CompiledProgram(train_program)
# compiled_prog = fluid.CompiledProgram(train_program)
# loss_data, = exe.run(compiled_prog,
# feed={"X": x},
# fetch_list=[loss.name])
......@@ -95,7 +95,7 @@ Notes:
Multi-card Training
#######################
In multi-card training, you can use :code:`fluid.compiler.CompiledProgram` to compile the :code:`fluid.Program`, and then call :code:`with_data_parallel`. For example:
In multi-card training, you can use :code:`fluid.CompiledProgram` to compile the :code:`fluid.Program`, and then call :code:`with_data_parallel`. For example:
.. code-block:: python
......@@ -108,7 +108,7 @@ In multi-card training, you can use :code:`fluid.compiler.CompiledProgram` to co
if not use_cuda:
os.environ['CPU_NUM'] = str(2)
compiled_prog = compiler.CompiledProgram(
compiled_prog = fluid.CompiledProgram(
train_program).with_data_parallel(
loss_name=loss.name)
loss_data, = exe.run(compiled_prog,
......
......@@ -19,20 +19,21 @@
通过克隆训练 :code:`fluid.Program` 生成测试 :code:`fluid.Program`
=======================================================================
用:code:`Program.clone()` 方法可以复制出新的 :code:`fluid.Program` 。 通过设置
:code:`Program.clone()` 方法可以复制出新的 :code:`fluid.Program` 。 通过设置
:code:`Program.clone(for_test=True)` 复制含有用于测试的操作 :code:`fluid.Program` 。简单的使用方法如下:
.. code-block:: python
import paddle.fluid as fluid
img = fluid.layers.data(name="image", shape=[784])
image = fluid.data(name="image", shape=[None, 784], dtype='float32')
label = fluid.data(name="label", shape=[None, 1], dtype="int64")
prediction = fluid.layers.fc(
input=fluid.layers.fc(input=img, size=100, act='relu'),
input=fluid.layers.fc(input=image, size=100, act='relu'),
size=10,
act='softmax'
)
label = fluid.layers.data(name="label", shape=[1], dtype="int64")
loss = fluid.layers.mean(fluid.layers.cross_entropy(input=prediction, label=label))
acc = fluid.layers.accuracy(input=prediction, label=label)
......@@ -64,9 +65,9 @@ PaddlePaddle Fluid中使用 :code:`fluid.unique_name` 包来随机初始化用
import paddle.fluid as fluid
def network(is_test):
file_obj = fluid.layers.open_files(filenames=["test.recordio"] if is_test else ["train.recordio"], ...)
img, label = fluid.layers.read_file(file_obj)
hidden = fluid.layers.fc(input=img, size=100, act="relu")
image = fluid.data(name="image", shape=[None, 784], dtype='float32')
label = fluid.data(name="label", shape=[None, 1], dtype="int64")
hidden = fluid.layers.fc(input=image, size=100, act="relu")
hidden = fluid.layers.batch_norm(input=hidden, is_test=is_test)
...
return loss
......
......@@ -25,13 +25,13 @@ Generate test :code:`fluid.Program` by cloning training :code:`fluid.Program`
import paddle.fluid as fluid
img = fluid.layers.data(name="image", shape=[784])
image = fluid.data(name="image", shape=[None, 784], dtype='float32')
label = fluid.data(name="label", shape=[None, 1], dtype="int64")
prediction = fluid.layers.fc(
input=fluid.layers.fc(input=img, size=100, act='relu'),
input=fluid.layers.fc(input=image, size=100, act='relu'),
size=10,
act='softmax'
)
label = fluid.layers.data(name="label", shape=[1], dtype="int64")
loss = fluid.layers.mean(fluid.layers.cross_entropy(input=prediction, label=label))
acc = fluid.layers.accuracy(input=prediction, label=label)
......@@ -56,9 +56,9 @@ For example:
import paddle.fluid as fluid
def network(is_test):
file_obj = fluid.layers.open_files(filenames=["test.recordio"] if is_test else ["train.recordio"], ...)
img, label = fluid.layers.read_file(file_obj)
hidden = fluid.layers.fc(input=img, size=100, act="relu")
image = fluid.data(name="image", shape=[None, 784], dtype='float32')
label = fluid.data(name="label", shape=[None, 1], dtype="int64")
hidden = fluid.layers.fc(input=image, size=100, act="relu")
hidden = fluid.layers.batch_norm(input=hidden, is_test=is_test)
...
return loss
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册