86
86
<br >
87
87
88
88
<p align =" center " >
89
- <img src =" https://raw.githubusercontent.com/PaddlePaddle/Paddle/develop/doc/fluid/images/fluid_compiler .png " width =100% >
89
+ <img src =" https://raw.githubusercontent.com/PaddlePaddle/Paddle/develop/doc/fluid/images/fluid-compiler .png " width =100% >
90
90
</p >
91
91
92
92
---
123
123
<font size =5 >
124
124
125
125
- 在科学计算领域,计算图是一种描述计算的经典方式。下图展示了从前向计算图(蓝色)开始,通过添加反向(红色)和优化算法相关(绿色)操作,构建出整个计算图的过程:
126
- -
126
+ -
127
127
<p align =" center " >
128
128
<img src =" https://raw.githubusercontent.com/PaddlePaddle/Paddle/develop/doc/fluid/images/graph_construction_example_all.png " width =60% >
129
129
</p >
130
130
131
-
131
+
132
132
- Fluid ==使用` Program ` 而不是计算图==来描述模型和优化过程。` Program ` 由` Block ` 、` Operator ` 和` Variable ` 构成,相关概念会在后文详细展开。
133
133
- 编译时 Fluid 接受前向计算(这里可以先简单的理解为是一段有序的计算流)` Program ` ,为这段前向计算按照:前向 -> 反向 -> 梯度 clip -> 正则 -> 优化 的顺序,添加相关 ` Operator ` 和` Variable ` 到` Program ` 到完整的计算。
134
134
328
328
329
329
</font >
330
330
331
- ---
331
+ ---
332
332
333
333
### 编译时概念 :==** [ Transpiler] ( https://github.com/PaddlePaddle/Paddle/blob/develop/doc/fluid/design/motivation/fluid_compiler.md ) ** ==
334
334
<font size =5 >
402
402
- ` Scope `
403
403
404
404
- 计算相关
405
- - ` Block `
405
+ - ` Block `
406
406
- ` Kernel ` 、` OpWithKernel ` 、` OpWithoutKernel `
407
407
408
408
<table >
439
439
</tbody >
440
440
</table >
441
441
442
- - 执行相关 :` Executor `
442
+ - 执行相关 :` Executor `
443
443
444
444
</font >
445
445
@@ -798,7 +798,7 @@ class GPUAllocator : public SystemAllocator {
798
798
799
799
- step 1:添加Place类型,<span style="background-color:#DAB1D5;">由用户实现添加到框架</span>
800
800
- 可以将Place类型理解为一个整数加上一个枚举型,包括:设备号 + 设备类型
801
-
801
+
802
802
<p align="center">
803
803
<img src="https://raw.githubusercontent.com/PaddlePaddle/Paddle/develop/doc/fluid/images/place.png" width=40%>
804
804
</p>
@@ -824,7 +824,7 @@ class GPUAllocator : public SystemAllocator {
824
824
1. DataType 执行数据类型 FP32/FP64/INT32/INT64
825
825
1. Memory layout: 运行时 Tensor 在内存中的排布格式 NCHW、 NHWC
826
826
1. 使用的库
827
-
827
+
828
828
来区分Kernel,为同一个operator注册多个 Kernel。
829
829
830
830
```cpp
@@ -876,7 +876,7 @@ step 3: 运行时的 KernelType 推断和Kernel切换,<span style="background-
876
876
namespace framework {
877
877
using LoDTensorArray = std::vector<LoDTensor>;
878
878
}
879
- }
879
+ }
880
880
```
881
881
- 每一次循环,从原始输入中“切出”一个片段
882
882
- LoDTensorArray 在Python端暴露,是Fluid支持的基础数据结构之一,用户可以直接创建并使用
@@ -910,7 +910,7 @@ void Run(const framework::Scope &scope,
910
910
false /*create_local_scope*/);
911
911
}
912
912
}
913
-
913
+
914
914
```
915
915
916
916
</font >
@@ -951,7 +951,7 @@ void Run(const framework::Scope &scope,
951
951
952
952
---
953
953
954
- #### dynamicRNN 中的 Memory
954
+ #### dynamicRNN 中的 Memory
955
955
956
956
<font size =5 >
957
957
@@ -961,7 +961,7 @@ void Run(const framework::Scope &scope,
961
961
- ` memory ` 在 operator A 前向计算之后,进行前向计算
962
962
- 当 ` memory ` 的前向计算会 "指向" A 的输出 LoDTensor
963
963
- ` memory ` 的输出可以是另一个 operator 的输入,于是形成了“循环”连接
964
-
964
+
965
965
</font >
966
966
967
967
---
@@ -1107,7 +1107,7 @@ void Run(const framework::Scope &scope,
1107
1107
<td >
1108
1108
<p align =" center " >
1109
1109
<img src =" https://raw.githubusercontent.com/PaddlePaddle/Paddle/develop/doc/fluid/images/fluid_module_1.png " width =60% >
1110
- </p >
1110
+ </p >
1111
1111
</td >
1112
1112
<td >
1113
1113
<p align =" center " >
@@ -1127,13 +1127,13 @@ void Run(const framework::Scope &scope,
1127
1127
<font size =5 >
1128
1128
1129
1129
- 设计概览
1130
- - 重构概览 [ ->] ( https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/refactorization.md )
1131
- - fluid [ ->] ( https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/fluid.md )
1130
+ - 重构概览 [ ->] ( https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/refactorization.md )
1131
+ - fluid [ ->] ( https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/fluid.md )
1132
1132
- fluid_compiler [ ->] ( https://github.com/PaddlePaddle/Paddle/blob/develop/doc/fluid/design/motivation/fluid_compiler.md )
1133
1133
- 核心概念
1134
1134
- variable 描述 [ ->] ( https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/var_desc.md )
1135
1135
- Tensor [ ->] ( https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/framework/tensor.md )
1136
- - LoDTensor [ ->] ( https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/framework/lod_tensor.md )
1136
+ - LoDTensor [ ->] ( https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/framework/lod_tensor.md )
1137
1137
- TensorArray [ ->] ( https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/tensor_array.md )
1138
1138
- Program [ ->] ( https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/program.md )
1139
1139
- Block [ ->] ( https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/block.md )
@@ -1152,7 +1152,7 @@ void Run(const framework::Scope &scope,
1152
1152
- 支持新设硬件设备库 [ ->] ( https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/support_new_device.md )
1153
1153
- 添加新的Operator [ ->] ( https://github.com/PaddlePaddle/Paddle/blob/develop/doc/howto/dev/new_op_cn.md )
1154
1154
- 添加新的Kernel [ ->] (
1155
- https://github.com/PaddlePaddle/Paddle/blob/develop/doc/howto/dev/new_op_kernel_en.md )
1155
+ https://github.com/PaddlePaddle/Paddle/blob/develop/doc/howto/dev/new_op_kernel_en.md )
1156
1156
1157
1157
</font >
1158
1158
@@ -1167,10 +1167,10 @@ https://github.com/PaddlePaddle/Paddle/blob/develop/doc/howto/dev/new_op_kernel_
1167
1167
<font size =5 >
1168
1168
1169
1169
Docker编译PaddlePaddle源码: [ ->] ( http://www.paddlepaddle.org/docs/develop/documentation/fluid/zh/build_and_install/docker_install_cn.html )
1170
-
1170
+
1171
1171
PaddlePaddle 在 Dockerhub 地址:[ ->] (
1172
1172
https://hub.docker.com/r/paddlepaddle/paddle/tags/ )
1173
-
1173
+
1174
1174
1 . 获取PaddlePaddle的Docker镜像
1175
1175
``` bash
1176
1176
docker pull paddlepaddle/paddle:latest-dev
@@ -1183,7 +1183,7 @@ PaddlePaddle 在 Dockerhub 地址:[->](
1183
1183
` ` `
1184
1184
1185
1185
1. 进入docker container后,从源码编译,请参考文档 [-> ]( http://www.paddlepaddle.org/docs/develop/documentation/fluid/zh/build_and_install/build_from_source_cn.html)
1186
-
1186
+
1187
1187
< /font>
1188
1188
1189
1189
---
@@ -1196,7 +1196,7 @@ PaddlePaddle 在 Dockerhub 地址:[->](
1196
1196
1. 开发推荐使用tag为` latest-dev` 的镜像,其中打包了所有编译依赖。` latest` 及` lastest-gpu` 是production镜像,主要用于运行PaddlePaddle程序。
1197
1197
2. 在Docker中运行GPU程序,推荐使用nvidia-docker,[否则需要将CUDA库和设备挂载到Docker容器内](http://www.paddlepaddle.org/docs/develop/documentation/fluid/zh/build_and_install/docker_install_cn.html)。
1198
1198
< font size=4>
1199
-
1199
+
1200
1200
` ` ` bash
1201
1201
nvidia-docker run -it -v $PWD /Paddle:/paddle paddlepaddle/paddle:latest-dev /bin/bash
1202
1202
` ` `
@@ -1353,9 +1353,9 @@ Op注册实现在`.cc`文件;Kernel注册CPU实现在`.cc`文件中,CUDA实
1353
1353
}
1354
1354
};
1355
1355
` ` `
1356
-
1356
+
1357
1357
< /font>
1358
-
1358
+
1359
1359
---
1360
1360
1361
1361
# ##### 实现带Kernel的Operator <span style="background-color:#c4e1e1;">step2</span>: 定义Operator类
@@ -1420,11 +1420,11 @@ class ClipOp : public framework::OperatorWithKernel {
1420
1420
2. override InferShape函数(参考 [clip_op](https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/fluid/operators/clip_op.cc#L24))
1421
1421
1422
1422
1. 什么是` functor` ?
1423
-
1423
+
1424
1424
- 类或结构体仅重载了` ()` ,一般是可被多个kernel复用的计算函数。
1425
1425
1426
1426
< font size=4>
1427
-
1427
+
1428
1428
` ` ` cpp
1429
1429
template < typename T>
1430
1430
class CrossEntropyFunctor< platform::CPUDeviceContext, T> {
@@ -1438,9 +1438,9 @@ class ClipOp : public framework::OperatorWithKernel {
1438
1438
};
1439
1439
```
1440
1440
< /font>
1441
-
1441
+
1442
1442
- 在 clip_op 内也会看到将一段计算函数抽象为functor的使用法: [-> ](https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/fluid/operators/clip_op.h#L27)。
1443
-
1443
+
1444
1444
< /font>
1445
1445
1446
1446
---
@@ -1504,7 +1504,7 @@ class ClipKernel : public framework::OpKernel<T> {
1504
1504
- 需要注意,< span style=" background-color:#e1c4c4;" > Fluid中,不区分Cost Op和中间层Op,所有Op都必须正确处理接收到的梯度< /span>
1505
1505
2. 反向Op的输出
1506
1506
- 对可学习参数的求导结果
1507
- - 对所有输入的求导结果
1507
+ - 对所有输入的求导结果
1508
1508
1509
1509
1510
1510
< /font>
@@ -1520,7 +1520,7 @@ class ClipKernel : public framework::OpKernel<T> {
1520
1520
1. 在` .cc` 文件中注册前向、反向Op类,注册CPU Kernel。
1521
1521
1522
1522
< font size=4>
1523
-
1523
+
1524
1524
` ` ` cpp
1525
1525
namespace ops = paddle::operators;
1526
1526
REGISTER_OP(clip, ops::ClipOp, ops::ClipOpMaker< float> , clip_grad,
@@ -1530,13 +1530,13 @@ class ClipKernel : public framework::OpKernel<T> {
1530
1530
REGISTER_OP_CPU_KERNEL(
1531
1531
clip_grad, ops::ClipGradKernel< paddle::platform::CPUDeviceContext, float> );
1532
1532
` ` `
1533
-
1533
+
1534
1534
- 在上面的代码片段中:
1535
1535
1536
1536
1. ` REGISTER_OP` : 注册` ops::ClipOp` 类,类型名为` clip` ,该类的` ProtoMaker` 为` ops::ClipOpMaker` ,注册` ops::ClipOpGrad` ,类型名为` clip_grad`
1537
1537
1. ` REGISTER_OP_WITHOUT_GRADIENT` : 用于注册没有反向的Op,例如:优化算法相关的Op
1538
1538
1. ` REGISTER_OP_CPU_KERNEL` :注册` ops::ClipKernel` 类,并特化模板参数为` paddle::platform::CPUPlace` 和` float` 类型,同理,注册` ops::ClipGradKernel` 类
1539
-
1539
+
1540
1540
< /font>
1541
1541
1. 按照同样方法,在` .cu` 文件中注册GPU Kernel
1542
1542
- < span style=" background-color:#e1c4c4;" > 如果CUDA Kernel的实现基于Eigen,需在 ` .cu` 的开始加上宏定义 ` # define EIGEN_USE_GPU` < /span>
@@ -1593,7 +1593,7 @@ class ClipKernel : public framework::OpKernel<T> {
1593
1593
```bash
1594
1594
make test ARGS="-R test_mul_op -V"
1595
1595
```
1596
-
1596
+
1597
1597
或者:
1598
1598
1599
1599
```
@@ -1613,7 +1613,7 @@ class ClipKernel : public framework::OpKernel<T> {
1613
1613
- 如果多个Op依赖一些共用的函数,可以创建非` *_op.* ` 格式的文件来存放,如` gather.h ` 文件。
1614
1614
1615
1615
</font >
1616
-
1616
+
1617
1617
---
1618
1618
1619
1619
### ==10.== 使用相关问题
@@ -1735,7 +1735,7 @@ class ClipKernel : public framework::OpKernel<T> {
1735
1735
y_data = np.random.randint(0 , 8 , [1 ]).astype(" int32" )
1736
1736
y_tensor = core.Tensor()
1737
1737
y_tensor.set(y_data, place)
1738
-
1738
+
1739
1739
x_data = np.random.uniform(0.1 , 1 , [11 , 8 ]).astype(" float32" )
1740
1740
x_tensor = core.Tensor()
1741
1741
x_tensor.set(x_data, place)
0 commit comments