未验证 提交 be9ff92a 编写于 作者: X xujiaqi01 提交者: GitHub

Merge branch 'master' into cu2

...@@ -96,9 +96,10 @@ cd paddlerec ...@@ -96,9 +96,10 @@ cd paddlerec
修改dnn模型的[超参配置](./models/rank/dnn/config.yaml),例如将迭代训练轮数从10轮修改为5轮: 修改dnn模型的[超参配置](./models/rank/dnn/config.yaml),例如将迭代训练轮数从10轮修改为5轮:
```yaml ```yaml
train: runner:
# epochs: 10 - name: runner1
epochs: 5 class: single_train
epochs: 5 # 10->5
``` ```
在Linux环境下,可以使用`vim`等文本编辑工具修改yaml文件: 在Linux环境下,可以使用`vim`等文本编辑工具修改yaml文件:
...@@ -126,9 +127,9 @@ python -m paddlerec.run -m ./models/rank/dnn/config.yaml ...@@ -126,9 +127,9 @@ python -m paddlerec.run -m ./models/rank/dnn/config.yaml
我们以dnn模型为例,在paddlerec代码目录下,修改dnn模型的`config.yaml`文件: 我们以dnn模型为例,在paddlerec代码目录下,修改dnn模型的`config.yaml`文件:
```yaml ```yaml
train: runner:
#engine: single - name: runner1
engine: local_cluster class: local_cluster_train # single_train -> local_cluster_train
``` ```
然后启动paddlerec训练: 然后启动paddlerec训练:
...@@ -142,9 +143,9 @@ python -m paddlerec.run -m ./models/rank/dnn/config.yaml ...@@ -142,9 +143,9 @@ python -m paddlerec.run -m ./models/rank/dnn/config.yaml
我们以dnn模型为例,在paddlerec代码目录下,首先修改dnn模型`config.yaml`文件: 我们以dnn模型为例,在paddlerec代码目录下,首先修改dnn模型`config.yaml`文件:
```yaml ```yaml
train: runner:
#engine: single - name: runner1
engine: cluster class: cluster_train # single_train -> cluster_train
``` ```
再添加分布式启动配置文件`backend.yaml`,具体配置规则在[分布式训练](doc/distributed_train.md)教程中介绍。最后启动paddlerec训练: 再添加分布式启动配置文件`backend.yaml`,具体配置规则在[分布式训练](doc/distributed_train.md)教程中介绍。最后启动paddlerec训练:
...@@ -177,7 +178,7 @@ python -m paddlerec.run -m ./models/rank/dnn/config.yaml -b backend.yaml ...@@ -177,7 +178,7 @@ python -m paddlerec.run -m ./models/rank/dnn/config.yaml -b backend.yaml
| 多任务 | [ESMM](models/multitask/esmm/model.py) | ✓ | ✓ | ✓ | | 多任务 | [ESMM](models/multitask/esmm/model.py) | ✓ | ✓ | ✓ |
| 多任务 | [MMOE](models/multitask/mmoe/model.py) | ✓ | ✓ | ✓ | | 多任务 | [MMOE](models/multitask/mmoe/model.py) | ✓ | ✓ | ✓ |
| 多任务 | [ShareBottom](models/multitask/share-bottom/model.py) | ✓ | ✓ | ✓ | | 多任务 | [ShareBottom](models/multitask/share-bottom/model.py) | ✓ | ✓ | ✓ |
| 重排序 | [Listwise](models/rerank/listwise/model.py) | ✓ | x | ✓ | | 重排序 | [Listwise](models/rerank/listwise/model.py) | ✓ | x | ✓ |
...@@ -203,6 +204,13 @@ python -m paddlerec.run -m ./models/rank/dnn/config.yaml -b backend.yaml ...@@ -203,6 +204,13 @@ python -m paddlerec.run -m ./models/rank/dnn/config.yaml -b backend.yaml
### 关于PaddleRec性能 ### 关于PaddleRec性能
* [Benchmark](doc/benchmark.md) * [Benchmark](doc/benchmark.md)
### 开发者教程
* [PaddleRec设计文档](doc/design.md)
* [二次开发](doc/development.md)
### 关于PaddleRec性能
* [Benchmark](doc/benchmark.md)
### FAQ ### FAQ
* [常见问题FAQ](doc/faq.md) * [常见问题FAQ](doc/faq.md)
......
# 二次开发
## 如何添加自定义模型
当您希望开发自定义模型时,需要继承模型的模板基类,并实现三个必要的方法`init_hyper_parameter`,`intput_data`,`net`
并按照以下规范添加代码。
### 基类的继承
继承`paddlerec.core.model`的ModelBase,命名为`Class Model`
```python
from paddlerec.core.model import ModelBase
class Model(ModelBase):
# 构造函数无需显式指定
# 若继承,务必调用基类的__init__方法
def __init__(self, config):
ModelBase.__init__(self, config)
# ModelBase的__init__方法会调用_init_hyper_parameter()
```
### 超参的初始化
继承并实现`_init_hyper_parameter`方法(必要),可以在该方法中,从`yaml`文件获取超参或进行自定义操作。如下面的示例:
所有的envs调用接口在_init_hyper_parameters()方法中实现,同时类成员也推荐在此做声明及初始化。
```python
def _init_hyper_parameters(self):
self.feature_size = envs.get_global_env(
"hyper_parameters.feature_size")
self.expert_num = envs.get_global_env("hyper_parameters.expert_num")
self.gate_num = envs.get_global_env("hyper_parameters.gate_num")
self.expert_size = envs.get_global_env("hyper_parameters.expert_size")
self.tower_size = envs.get_global_env("hyper_parameters.tower_size")
```
### 数据输入的定义
继承并实现`input_data`方法(非必要)
#### 直接使用基类的数据读取方法
`ModelBase`中的input_data默认实现为slot_reader,在`config.yaml`中分别配置`reader.sparse_slot``reader.dense_slot`选项实现`slog:feasign`模式的数据读取。
> Slot : Feasign 是什么?
>
> Slot直译是槽位,在Rec工程中,是指某一个宽泛的特征类别,比如用户ID、性别、年龄就是Slot,Feasign则是具体值,比如:12345,男,20岁。
>
> 在实践过程中,很多特征槽位不是单一属性,或无法量化并且离散稀疏的,比如某用户兴趣爱好有三个:游戏/足球/数码,且每个具体兴趣又有多个特征维度,则在兴趣爱好这个Slot兴趣槽位中,就会有多个Feasign值。
>
> PaddleRec在读取数据时,每个Slot ID对应的特征,支持稀疏,且支持变长,可以非常灵活的支持各种场景的推荐模型训练。
使用示例请参考`rank.dnn`模型。
#### 自定义数据输入
如果您不想使用`slot:feasign`模式,则需继承并实现`input_data`接口,接口定义:`def input_data(self, is_infer=False, **kwargs)`
使用示例如下:
```python
def input_data(self, is_infer=False, **kwargs):
ser_slot_names = fluid.data(
name='user_slot_names',
shape=[None, 1],
dtype='int64',
lod_level=1)
item_slot_names = fluid.data(
name='item_slot_names',
shape=[None, self.item_len],
dtype='int64',
lod_level=1)
lens = fluid.data(name='lens', shape=[None], dtype='int64')
labels = fluid.data(
name='labels',
shape=[None, self.item_len],
dtype='int64',
lod_level=1)
train_inputs = [user_slot_names] + [item_slot_names] + [lens] + [labels]
infer_inputs = [user_slot_names] + [item_slot_names] + [lens]
if is_infer:
return infer_inputs
else:
return train_inputs
```
更多数据读取教程,请参考[自定义数据集及Reader](custom_dataset_reader.md)
### 组网的定义
继承并实现`net`方法(必要)
- 接口定义`def net(self, inputs, is_infer=False)`
- 自定义网络需在该函数中使用paddle组网,实现前向逻辑,定义网络的Loss及Metrics,通过`is_infer`判断是否为infer网络。
- 我们强烈建议`train``infer`尽量复用相同代码,
- `net`中调用的其他函数以下划线为头进行命名,封装网络中的结构模块,如`_sparse_embedding_layer(self)`
- `inputs``def input_data()`的输出,若使用`slot_reader`方式,inputs为占位符,无实际意义,通过以下方法拿到dense及sparse的输入
```python
self.sparse_inputs = self._sparse_data_var[1:]
self.dense_input = self._dense_data_var[0]
self.label_input = self._sparse_data_var[0]
```
可以参考官方模型的示例学习net的构造方法。
## 如何运行自定义模型
记录`model.py`,`config.yaml`及数据读取`reader.py`的文件路径,建议置于同一文件夹下,如`/home/custom_model`下,更改`config.yaml`中的配置选项
1. 更改 workerspace为模型文件所在文件夹
```yaml
workspace: "/home/custom_model"
```
2. 更改数据地址及读取reader地址
```yaml
dataset:
- name: custom_model_train
- data_path: "{workspace}/data/train" # or "/home/custom_model/data/train"
- data_converter: "{workspace}/reader.py" # or "/home/custom_model/reader.py"
```
3. 更改执行器的路径配置
```yaml
mode: train_runner
runner:
- name: train_runner
class: single_train
device: cpu
epochs: 10
save_checkpoint_interval: 2
save_inference_interval: 5
save_checkpoint_path: "{workspace}/increment" # or "/home/custom_model/increment"
save_inference_path: "{workspace}/inference" # or "/home/custom_model/inference"
print_interval: 10
phase:
- name: train
model: "{workspace}/model.py" # or "/home/custom_model/model"
dataset_name: custom_model_train
thread_num: 1
```
4. 使用paddlerec.run方法运行自定义模型
```shell
python -m paddlerec.run -m /home/custom_model/config.yaml
```
以上~请开始享受你的推荐算法高效开发流程。如有任何问题,欢迎在[issue](https://github.com/PaddlePaddle/PaddleRec/issues)提出,我们会第一时间跟进解决。
``` ```yaml
# 全局配置 # 全局配置
# Debug 模式开关,Debug模式下,会打印OP的耗时及IO占比
debug: false debug: false
workspace: "."
# 工作区目录
# 使用文件夹路径,则会在该目录下寻找超参配置,组网,数据等必须文件
workspace: "/home/demo_model/"
# 若 workspace: paddlerec.models.rank.dnn
# 则会使用官方默认配置与组网
# 用户可以配多个dataset,exector里不同阶段可以用不同的dataset # 用户可以指定多个dataset(数据读取配置)
# 运行的不同阶段可以使用不同的dataset
dataset: dataset:
- name: sample_1 # dataloader 示例
type: DataLoader #或者QueueDataset - name: dataset_1
type: DataLoader
batch_size: 5 batch_size: 5
data_path: "{workspace}/data/train" data_path: "{workspace}/data/train"
# 用户自定义reader # 指定自定义的reader.py所在路径
data_converter: "{workspace}/rsc15_reader.py" data_converter: "{workspace}/rsc15_reader.py"
- name: sample_2 # QueueDataset 示例
type: QueueDataset #或者DataLoader - name: dataset_2
type: QueueDataset
batch_size: 5 batch_size: 5
data_path: "{workspace}/data/train" data_path: "{workspace}/data/train"
# 用户可以配置sparse_slots和dense_slots,无需再定义data_converter # 用户可以配置sparse_slots和dense_slots,无需再定义data_converter,使用默认reader
sparse_slots: "click ins_weight 6001 6002 6003 6005 6006 6007 6008 6009" sparse_slots: "click ins_weight 6001 6002 6003 6005 6006 6007 6008 6009"
dense_slots: "readlist:9" dense_slots: "readlist:9"
#示例一,用户自定义参数,用于组网配置 # 自定义超参数,主要涉及网络中的模型超参及优化器
hyper_parameters: hyper_parameters:
#优化器 #优化器
optimizer optimizer:
class: Adam class: Adam # 直接配置Optimizer,目前支持sgd/Adam/AdaGrad
learning_rate: 0.001 learning_rate: 0.001
strategy: "{workspace}/conf/config_fleet.py" strategy: "{workspace}/conf/config_fleet.py" # 使用大规模稀疏pslib模式的特有配置
# 用户自定义配置 # 模型超参
vocab_size: 1000 vocab_size: 1000
hid_size: 100 hid_size: 100
my_key1: 233
my_key2: 0.1
mode: runner1 # 通过全局参数mode指定当前运行的runner
mode: runner_1
# runner主要涉及模型的执行环境,如:单机/分布式,CPU/GPU,迭代轮次,模型加载与保存地址
runner: runner:
- name: runner1 # 示例一,train - name: runner_1 # 配置一个runner,进行单机的训练
trainer_class: single_train class: single_train # 配置运行模式的选择,还可以选择:single_infer/local_cluster_train/cluster_train
epochs: 10 epochs: 10
device: cpu device: cpu
init_model_path: "" init_model_path: ""
...@@ -50,14 +59,16 @@ runner: ...@@ -50,14 +59,16 @@ runner:
save_checkpoint_path: "xxxx" save_checkpoint_path: "xxxx"
save_inference_path: "xxxx" save_inference_path: "xxxx"
- name: runner2 # 示例二,infer - name: runner_2 # 配置一个runner,进行单机的预测
trainer_class: single_train class: single_infer
epochs: 1 epochs: 1
device: cpu device: cpu
init_model_path: "afs:/xxx/xxx" init_model_path: "afs:/xxx/xxx"
# 模型在训练时,可能存在多个阶段,每个阶段的组网与数据读取都可能不尽相同
# 每个runner都会完整的运行所有阶段
# phase指定运行时加载的模型及reader
phase: phase:
- name: phase1 - name: phase1
model: "{workspace}/model.py" model: "{workspace}/model.py"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册