Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
BaiXuePrincess
PaddleRec
提交
d6c6053e
P
PaddleRec
项目概览
BaiXuePrincess
/
PaddleRec
与 Fork 源项目一致
Fork自
PaddlePaddle / PaddleRec
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleRec
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
d6c6053e
编写于
6月 11, 2020
作者:
T
tangwei12
提交者:
GitHub
6月 11, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' into add_readme
上级
f1813a3d
e8867282
变更
7
显示空白变更内容
内联
并排
Showing
7 changed file
with
305 addition
and
61 deletion
+305
-61
README.md
README.md
+5
-5
doc/design.md
doc/design.md
+45
-33
doc/model_develop.md
doc/model_develop.md
+0
-0
doc/predict.md
doc/predict.md
+1
-1
doc/serving.md
doc/serving.md
+1
-1
doc/train.md
doc/train.md
+72
-21
doc/trainer_develop.md
doc/trainer_develop.md
+181
-0
未找到文件。
README.md
浏览文件 @
d6c6053e
...
...
@@ -129,8 +129,8 @@ python -m paddlerec.run -m paddlerec.models.rank.dnn
### 进阶教程
*
[
自定义Reader
](
doc/custom_reader.md
)
*
[
自定义模型
](
doc/
development
.md
)
*
[
自定义流程
](
doc/
development
.md
)
*
[
自定义模型
](
doc/
model_develop
.md
)
*
[
自定义流程
](
doc/
trainer_develop
.md
)
*
[
yaml配置说明
](
doc/yaml.md
)
*
[
PaddleRec设计文档
](
doc/design.md
)
...
...
doc/design.md
浏览文件 @
d6c6053e
...
...
@@ -4,17 +4,13 @@
## PaddleRec 整体设计概览
PaddleRec将推荐模型的训练与预测流程,整体抽象为了五个大模块:
*
[
Engine 流程执行引擎
](
#engine
)
*
[
Trainer 流程具体定义
](
#trainer
)
*
[
Model 模型组网定义
](
#model
)
*
[
Reader 数据读取定义
](
#reader
)
*
[
Metric 精度指标打印
](
#metric
)
层级结构,以及一键启动训练时的调用关系如下图所示:
<p
align=
"center"
>
<img
align=
"center"
src=
"imgs/design.png"
>
<p>
-
[
PaddleRec 设计
](
#paddlerec-设计
)
-
[
PaddleRec 整体设计概览
](
#paddlerec-整体设计概览
)
-
[
Engine
](
#engine
)
-
[
Trainer
](
#trainer
)
-
[
Model
](
#model
)
-
[
Reader
](
#reader
)
-
[
Metric
](
#metric
)
core的文件结构如下,后续分别对各个模块进行介绍。
```
...
...
@@ -50,7 +46,7 @@ Engine是整体训练的执行引擎,与组网逻辑及数据无关,只与
运行设备是指:
-
CPU
-
GPU
-
AI芯片
-
其他
AI芯片
在用户调用
`python -m paddlerec.run`
时,首先会根据
`yaml`
文件中的配置信息选择合适的执行引擎, 以下代码位于
[
run.py
](
../run.py
)
:
```
python
...
...
@@ -62,15 +58,36 @@ engine.run()
我们以
`single engine`
为例,概览engine的行为:
```
python
def
single_engine
(
args
):
trainer
=
get_trainer_prefix
(
args
)
+
"SingleTrainer"
def
single_train_engine
(
args
):
_envs
=
envs
.
load_yaml
(
args
.
model
)
run_extras
=
get_all_inters_from_yaml
(
args
.
model
,
[
"train."
,
"runner."
])
trainer_class
=
run_extras
.
get
(
"runner."
+
_envs
[
"mode"
]
+
".trainer_class"
,
None
)
if
trainer_class
:
trainer
=
trainer_class
else
:
trainer
=
"GeneralTrainer"
executor_mode
=
"train"
fleet_mode
=
run_extras
.
get
(
"runner."
+
_envs
[
"mode"
]
+
".fleet_mode"
,
"ps"
)
device
=
run_extras
.
get
(
"runner."
+
_envs
[
"mode"
]
+
".device"
,
"cpu"
)
selected_gpus
=
run_extras
.
get
(
"runner."
+
_envs
[
"mode"
]
+
".selected_gpus"
,
"0"
)
selected_gpus_num
=
len
(
selected_gpus
.
split
(
","
))
if
device
.
upper
()
==
"GPU"
:
assert
selected_gpus_num
==
1
,
"Single Mode Only Support One GPU, Set Local Cluster Mode to use Multi-GPUS"
single_envs
=
{}
single_envs
[
"selsected_gpus"
]
=
selected_gpus
single_envs
[
"FLAGS_selected_gpus"
]
=
selected_gpus
single_envs
[
"train.trainer.trainer"
]
=
trainer
single_envs
[
"fleet_mode"
]
=
fleet_mode
single_envs
[
"train.trainer.executor_mode"
]
=
executor_mode
single_envs
[
"train.trainer.threads"
]
=
"2"
single_envs
[
"train.trainer.engine"
]
=
"single"
single_envs
[
"train.trainer.device"
]
=
args
.
device
single_envs
[
"train.trainer.platform"
]
=
envs
.
get_platform
()
print
(
"use {} engine to run model: {}"
.
format
(
trainer
,
args
.
model
))
single_envs
[
"train.trainer.engine"
]
=
"single"
set_runtime_envs
(
single_envs
,
args
.
model
)
trainer
=
TrainerFactory
.
create
(
args
.
model
)
...
...
@@ -91,34 +108,29 @@ Engine的自定义实现,可以参考[local_cluster.py](../core/engine/local_c
`Trainer`
是训练与预测流程的具体实现,会run模型中定义的各个流程,与model、reader、metric紧密相关。PaddleRec以有限状态机的逻辑定义了训练中的各个阶段,不同的Trainer子类会分别实现阶段中的特殊需求。有限状态机的流程在
`def processor_register()`
中注册。
我们以
Single
Trainer为例,概览Trainer行为:
我们以
General
Trainer为例,概览Trainer行为:
```
python
class
SingleTrainer
(
TranspileTrainer
):
def
processor_register
(
self
):
print
(
"processor_register begin"
)
self
.
regist_context_processor
(
'uninit'
,
self
.
instance
)
self
.
regist_context_processor
(
'
init_pass'
,
self
.
init
)
self
.
regist_context_processor
(
'
network_pass'
,
self
.
network
)
self
.
regist_context_processor
(
'startup_pass'
,
self
.
startup
)
if
envs
.
get_platform
()
==
"LINUX"
and
envs
.
get_global_env
(
"dataset_class"
,
None
,
"train.reader"
)
!=
"DataLoader"
:
self
.
regist_context_processor
(
'train_pass'
,
self
.
dataset_train
)
else
:
self
.
regist_context_processor
(
'train_pass'
,
self
.
dataloader_train
)
self
.
regist_context_processor
(
'infer_pass'
,
self
.
infer
)
self
.
regist_context_processor
(
'train_pass'
,
self
.
runner
)
self
.
regist_context_processor
(
'terminal_pass'
,
self
.
terminal
)
```
SingleTrainer首先注册了完成任务所需的步骤,各步骤首先按照注册顺序加入
`Trainer`
基类中名为
`status_processor`
的字典,运行的先后顺序,可以在每个执行步骤中改变
`context['status']`
的值,指定下一步运行哪个步骤。
SingleTrainer指定了以下6个步骤:
1.
uninit:默认排在首位,通过环境变量决定model的对象
1.
init_pass:调用model_的接口,生成模型的组网,初始化fetch及metric的变量
2.
startup_pass:初始化模型组网中的各个参数,run(fluid.default_startup_program)
3.
train_pass:会根据环境分别调用
`dataset`
与
`dataloader`
进行训练的流程。
4.
infer_pass:在训练结束后,会对训练保存的模型在测试集上验证效果
5.
terminal_pass:打印全局变量及预测结果等自定义的信息。
SingleTrainer指定了以下5个步骤:
1.
uninit:默认排在首位,通过环境变量启动paddle分布式的实例,执行在模型训练前的所有操作。
2.
network_pass:根据模型组网生成训练的program
3.
startup_pass:初始化模型组网中的各个参数,以及加载模型
4.
train_pass:会根据环境分别调用
`dataset`
与
`dataloader`
进行训练的流程。
5.
terminal_pass:停止worker,以及执行模型训练后的所有操作
Trainer的自定义实现,可以参照
[
single_trainer.py
](
../core/trainers/single
_trainer.py
)
Trainer的自定义实现,可以参照
[
general_trainer.py
](
../core/trainers/general
_trainer.py
)
## Model
...
...
doc/
development
.md
→
doc/
model_develop
.md
浏览文件 @
d6c6053e
文件已移动
doc/predict.md
浏览文件 @
d6c6053e
...
...
@@ -9,7 +9,7 @@ mode: runner_infer # 执行名为 runner1 的运行器
runner
:
-
name
:
runner_infer
# 定义 runner 名为 runner1
class
:
single_infer
# 执行单机预测 class = single_
infer
class
:
infer
# 执行单机预测 class =
infer
device
:
cpu
# 执行在 cpu 上
init_model_path
:
"
init_model"
# 指定初始化模型的地址
print_interval
:
10
# 预测信息的打印间隔,以batch为单位
...
...
doc/serving.md
浏览文件 @
d6c6053e
...
...
@@ -9,7 +9,7 @@ mode: runner_train # 执行名为 runner_train 的运行器
runner
:
-
name
:
runner_train
# 定义 runner 名为 runner_train
class
:
single_train
# 执行单机训练 class = single_
train
class
:
train
# 执行单机训练 class =
train
device
:
cpu
# 执行在 cpu 上
epochs
:
10
# 训练轮数
...
...
doc/train.md
浏览文件 @
d6c6053e
# PaddleRec 启动训练
## 启动方法
### 1. 启动内置模型的默认配置训练
...
...
@@ -27,29 +29,34 @@ python -m paddlerec.run -m paddlerec.models.recall.word2vec
-
**没有改动模型组网**
假如你将paddlerec代码库克隆在了
`/home/PaddleRec`
,并修改了
`/home/PaddleRec/models/rank/dnn/config.yaml`
,则如下启动训练
假如你将paddlerec代码库克隆在了
`/home/PaddleRec`
,并修改了
`/home/PaddleRec/models/rank/dnn/config.yaml`
,则如下启动训练
```
shell
python
-m
paddlerec.run
-m
/home/PaddleRec/models/rank/dnn/config.yaml
```
```
shell
python
-m
paddlerec.run
-m
/home/PaddleRec/models/rank/dnn/config.yaml
```
paddlerec 运行的是在paddlerec库安装目录下的组网文件(model.py)
paddlerec 运行的是在paddlerec库安装目录下的组网文件(model.py),但个性化配置
`config.yaml`
是用的是指定路径下的yaml文件。
-
**改动了模型组网**
假如你将paddlerec代码库克隆在了
`/home/PaddleRec`
,并修改了
`/home/PaddleRec/models/rank/dnn/model.py`
, 以及
`/home/PaddleRec/models/rank/dnn/config.yaml`
,则首先需要更改
`yaml`
中的
`workspace`
的设置:
假如你将paddlerec代码库克隆在了
`/home/PaddleRec`
,并修改了
`/home/PaddleRec/models/rank/dnn/model.py`
, 以及
`/home/PaddleRec/models/rank/dnn/config.yaml`
,则首先需要更改
`yaml`
中的
`workspace`
的设置:
```
yaml
workspace
:
/home/PaddleRec/models/rank/dnn/
```
```
yaml
workspace
:
/home/PaddleRec/models/rank/dnn/
```
再执行:
再执行:
```
shell
python
-m
paddlerec.run
-m
/home/PaddleRec/models/rank/dnn/config.yaml
```
```
shell
python
-m
paddlerec.run
-m
/home/PaddleRec/models/rank/dnn/config.yaml
```
paddlerec 运行的是绝对路径下的组网文件(model.py)以及个性化配置文件(config.yaml)
paddlerec 运行的是绝对路径下的组网文件(model.py)
## yaml训练配置
### yaml中训练相关的概念
...
...
@@ -58,19 +65,18 @@ paddlerec 运行的是绝对路径下的组网文件(model.py)
-
**`runner`**
: runner是训练的引擎,亦可称之为运行器,在runner中定义执行设备(cpu、gpu),执行的模式(训练、预测、单机、多机等),以及运行的超参,例如训练轮数,模型保存地址等。
-
**`phase`**
: phase是训练中的阶段的概念,是引擎具体执行的内容,该内容是指:具体运行哪个模型文件,使用哪个reader。
PaddleRec每次运行时,
只会执行一个运行器,通过
`mode`
指定
`runner`
的名字。但
每个运行器可以执行多个
`phase`
,所以PaddleRec支持一键启动多阶段的训练。
PaddleRec每次运行时,
会执行一个运行器,通过
`mode`
指定
`runner`
的名字。
每个运行器可以执行多个
`phase`
,所以PaddleRec支持一键启动多阶段的训练。
### 单机CPU训练
### 单机训练启动配置
下面我们开始定义一个单机训练的
`runner`
:
下面我们开始定义一个单机CPU训练的
`runner`
:
```
yaml
mode
:
runner_train
# 执行名为 runner
_train 的运行器
mode
:
single_cpu_train
# 执行名为 single_cpu
_train 的运行器
runner
:
-
name
:
runner_train
# 定义 runner 名为 runner
_train
class
:
single_train
# 执行单机训练 class =
single_train
-
name
:
single_cpu_train
# 定义 runner 名为 single_cpu
_train
class
:
train
# 执行单机训练,亦可为
single_train
device
:
cpu
# 执行在 cpu 上
epochs
:
10
# 训练轮数
...
...
@@ -101,3 +107,48 @@ dataset:
dense_slots
:
"
dense_var:13"
# dense参数的维度定义
```
### 单机单卡GPU训练
具体执行内容与reader与前述相同,下面介绍需要改动的地方
```
yaml
mode
:
single_gpu_train
# 执行名为 single_gpu_train 的运行器
runner
:
-
name
:
single_gpu_train
# 定义 runner 名为 single_gpu_train
class
:
train
# 执行单机训练,亦可为 single_train
device
:
gpu
# 执行在 gpu 上
selected_gpus
:
"
0"
# 默认选择在id=0的卡上执行训练
epochs
:
10
# 训练轮数
```
### 单机多卡GPU训练
具体执行内容与reader与前述相同,下面介绍需要改动的地方
```
yaml
mode
:
single_multi_gpu_train
# 执行名为 single_multi_gpu_train 的运行器
runner
:
-
name
:
single_multi_gpu_train
# 定义 runner 名为 single_multi_gpu_train
class
:
train
# 执行单机训练,亦可为 single_train
device
:
gpu
# 执行在 gpu 上
selected_gpus
:
"
0,1,2,3"
# 选择多卡执行训练
epochs
:
10
# 训练轮数
```
### 本地模拟参数服务器训练
具体执行内容与reader与前述相同,下面介绍需要改动的地方
```
yaml
mode
:
local_cluster_cpu_train
# 执行名为 local_cluster_cpu_train 的运行器
runner
:
-
name
:
local_cluster_cpu_train
# 定义 runner 名为 runner_train
class
:
local_cluster
# 执行本地模拟分布式——参数服务器训练
device
:
cpu
# 执行在 cpu 上(paddle后续版本会支持PS-GPU)
worker_num
:
1
# (可选)worker进程数量,默认1
server_num
:
1
# (可选)server进程数量,默认1
epochs
:
10
# 训练轮数
```
doc/trainer_develop.md
0 → 100644
浏览文件 @
d6c6053e
# 如何添加自定义流程
模型训练的流程也可以像
`model`
及
`reader`
一样,由用户自定义,并在
`config.yaml`
中指定路径,由PaddleRec调用。
PaddleRec可自定义的流程有如下5个:
1.
**instance**
: 执行训练前的所有操作
2.
**network**
:执行组网的前向/反向,训练策略的添加
3.
**startup**
:执行模型的初始化,加载
4.
**runnner**
: 执行模型的训练
5.
**terminal**
: 执行训练后的所有操作
## instance
instance由GeneralTrainer首先调用,执行模型组网前的所有操作。用户可以在这里进行下载数据,import不同的包,配置环境变量等操作。instance的官方实现位于
[
instance.py
](
../core/trainers/framework/instance.py
)
,instance基类定义如下:
```
python
class
InstanceBase
(
object
):
def
__init__
(
self
,
context
):
pass
def
instance
(
self
,
context
):
pass
```
您需要继承
`InstanceBase`
并命名为
`Instance`
,完成
`instance`
的实现,通过上下文信息字典
`context`
拿到模型所需信息,及保存相关配置。
## network
network将在instanc后调用,执行模型的组网。network的官方实现位于
[
network.py
](
../core/trainers/framework/network.py
)
,network基类定义如下:
```
python
class
NetworkBase
(
object
):
def
__init__
(
self
,
context
):
pass
def
build_network
(
self
,
context
):
pass
```
可参照其他模式的实现方式,自定其中的部分步骤。您需要您需要继承
`NetworkBase`
并命名为
`Network`
,完成
`build_network`
的实现,通过上下文信息字典
`context`
拿到模型所需信息,并在context中保存模型的program与scope信息,例如:
```
python
context
[
"model"
][
model_dict
[
"name"
]][
"main_program"
]
=
train_program
context
[
"model"
][
model_dict
[
"name"
]][
"startup_program"
]
=
startup_program
context
[
"model"
][
model_dict
[
"name"
]][
"scope"
]
=
scope
context
[
"model"
][
model_dict
[
"name"
]][
"model"
]
=
model
context
[
"model"
][
model_dict
[
"name"
]][
"default_main_program"
]
=
train_program
.
clone
()
```
## startup
startup执行网络参数的初始化,抑或模型的热启动,主要功能是执行
`exe.run(fluid.default_startup_program())`
。 startup的官方实现在
[
startup
](
../core/trainers/framework/startup.py
)
```
python
class
StartupBase
(
object
):
def
__init__
(
self
,
context
):
pass
def
startup
(
self
,
context
):
pass
def
load
(
self
,
context
,
is_fleet
=
False
,
main_program
=
None
):
dirname
=
envs
.
get_global_env
(
"runner."
+
context
[
"runner_name"
]
+
".init_model_path"
,
None
)
if
dirname
is
None
or
dirname
==
""
:
return
print
(
"going to load "
,
dirname
)
if
is_fleet
:
context
[
"fleet"
].
load_persistables
(
context
[
"exe"
],
dirname
)
else
:
fluid
.
io
.
load_persistables
(
context
[
"exe"
],
dirname
,
main_program
=
main_program
)
```
自定义startup流程,您需要您需要继承
`StartupBase`
并命名为
`Startup`
,实现该类型中startup成员函数。
## runner
runner是运行的主要流程,主要功能是reader的运行,网络的运行,指标的打印以及模型的保存。以参数服务器Runner为示例,如下:
```
python
class
PSRunner
(
RunnerBase
):
def
__init__
(
self
,
context
):
print
(
"Running PSRunner."
)
pass
def
run
(
self
,
context
):
# 通过超参拿到迭代次数
epochs
=
int
(
envs
.
get_global_env
(
"runner."
+
context
[
"runner_name"
]
+
".epochs"
))
# 取第一个phase的模型与reader
model_dict
=
context
[
"env"
][
"phase"
][
0
]
for
epoch
in
range
(
epochs
):
begin_time
=
time
.
time
()
# 调用run进行训练
self
.
_run
(
context
,
model_dict
)
end_time
=
time
.
time
()
seconds
=
end_time
-
begin_time
print
(
"epoch {} done, use time: {}"
.
format
(
epoch
,
seconds
))
with
fluid
.
scope_guard
(
context
[
"model"
][
model_dict
[
"name"
]][
"scope"
]):
train_prog
=
context
[
"model"
][
model_dict
[
"name"
]][
"main_program"
]
startup_prog
=
context
[
"model"
][
model_dict
[
"name"
]][
"startup_program"
]
with
fluid
.
program_guard
(
train_prog
,
startup_prog
):
# 保存模型
self
.
save
(
epoch
,
context
,
True
)
context
[
"status"
]
=
"terminal_pass"
```
自定义runner需要参照官方实现
[
runner.py
](
../core/trainers/framework/startup.py
)
,继承基类
`RunnerBase`
,命名为
`Runner`
,并实现
`run`
成员函数。
## terminal
terminal主要进行分布式训练结束后的
`stop worker`
,以及其他需要在模型训练完成后进行的工作,比如数据整理,模型上传等等。
```
python
class
TerminalBase
(
object
):
def
__init__
(
self
,
context
):
pass
def
terminal
(
self
,
context
):
print
(
"PaddleRec Finish"
)
```
自定义terminal需要继承
`TerminalBase`
命名为
`Terminal`
,并实现成员函数
`terminal`
。
## 自定义流程参与训练
假如我们自定义了某个流程,将其与model/reader一样,放在workspace下,并同时更改yaml配置中的runner相关选项,PaddleRec会自动用指定的流程替换原始的类别。
```
yaml
runner
:
-
name
:
train_runner
class
:
single_train
epochs
:
2
device
:
cpu
instance_class_path
:
"
{workspace}/your_instance.py"
network_class_path
:
"
{workspace}/your_network.py"
startup_class_path
:
"
{workspace}/your_startup.py"
runner_class_path
:
"
{workspace}/your_runner.py"
terminal_class_path
:
"
{workspace}/your_terminal.py"
print_interval
:
1
```
## 示例
官方模型中的TDM是一个很好的示例,该模型自定义了
`startup`
的实现,可以参考
[
tdm_startup.py
](
../models/treebased/tdm/tdm_startup.py
)
```
python
class
Startup
(
StartupBase
):
def
startup
(
self
,
context
):
logger
.
info
(
"Run TDM Trainer Startup Pass"
)
if
context
[
"engine"
]
==
EngineMode
.
SINGLE
:
self
.
_single_startup
(
context
)
else
:
self
.
_cluster_startup
(
context
)
context
[
'status'
]
=
'train_pass'
def
_single_startup
(
self
,
context
):
# single process
def
_cluster_startup
(
self
,
context
):
# cluster process
```
于此同时,在yaml中更改了默认的startup执行类:
```
yaml
runner
:
-
name
:
runner1
class
:
single_train
startup_class_path
:
"
{workspace}/tdm_startup.py"
epochs
:
10
device
:
cpu
```
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录