未验证 提交 6ef6adcb 编写于 作者: X Xiaoyao Xi 提交者: GitHub

Merge pull request #6 from xixiaoyao/master

update readme and delete fp16
...@@ -17,8 +17,8 @@ git clone https://github.com/PaddlePaddle/PALM.git ...@@ -17,8 +17,8 @@ git clone https://github.com/PaddlePaddle/PALM.git
## 目录结构 ## 目录结构
- backbone: 多任务学习的主干网络表示,支持bert, ernie, xlnet等,用户可自定义添加 - backbone: 多任务学习的主干网络表示,支持bert, ernie等,用户可自定义添加
- config:存放各个任务的配置文件,用户添加任务时需在此建立该任务的配置文件 - config:存放各个任务实例的配置文件,用户添加任务时需在此建立该任务的配置文件
- data: 存放各个任务的数据集 - data: 存放各个任务的数据集
- pretrain_model: 存放预训练模型、字典及其相关配置 - pretrain_model: 存放预训练模型、字典及其相关配置
- optimizer: 优化器,用户可在此自定义优化器 - optimizer: 优化器,用户可在此自定义优化器
...@@ -49,7 +49,7 @@ bash run.sh ...@@ -49,7 +49,7 @@ bash run.sh
- do_train:*(bool)* 训练标志位 - do_train:*(bool)* 训练标志位
- do_predict:*(bool)* 预测标志位,目前仅支持对主任务进行预测 - do_predict:*(bool)* 预测标志位,目前仅支持对主任务进行预测
- checkpoint_path: *(str)* 模型保存、训练断点恢复和预测模型载入路径,从该路径载入模型时默认读取最后一个训练step的模型 - checkpoint_path: *(str)* 模型保存、训练断点恢复和预测模型载入路径,从该路径载入模型时默认读取最后一个训练step的模型
- backbone_model:*(str)* 使用的骨干网络,名称选取自`backbone`目录下的模块 - backbone_model:*(str)* 使用的骨干网络,名称选取自`backbone`目录下的模块。注意,更换backbone时,若使用预训练模型,应同步更换预训练模型参数、配置和字典等相关字段
- vocab_path:*(str)* 字典文件,纯文本格式存储,其中每行为一个单词 - vocab_path:*(str)* 字典文件,纯文本格式存储,其中每行为一个单词
- optimizer:*(str)* 优化器名称,名称选取自`optimizer`中的文件名 - optimizer:*(str)* 优化器名称,名称选取自`optimizer`中的文件名
- learning_rate:*(str)* 训练阶段的学习率 - learning_rate:*(str)* 训练阶段的学习率
...@@ -74,7 +74,7 @@ bash run.sh ...@@ -74,7 +74,7 @@ bash run.sh
### 使用示例 ### 使用示例
若内置任务可满足用户需求,或用户已经完成自定义任务的添加,可通过如下方式直接启动多任务学习。 若内置任务可满足用户需求,或用户已经完成自定义任务的添加,可通过如下方式直接启动多任务学习。
例如,框架中内置了一个小数据集,包含MRQA阅读理解评测数据`mrqa`、MaskLM训练数据`mlm4mrqa`和问题与答案所在上下文的匹配数据集`am4mrqa`,而在框架中已经内置了机器阅读理解任务(`reading_comprehension`)、问答匹配任务(`answer_matching`)和掩码语言模型任务(`mask_language_model`),用户可通过如下流程完成多任务学习的启动。 例如,框架中内置了一个小数据集,包含MRQA阅读理解评测数据`mrqa`、MaskLM训练数据`mlm4mrqa`和问题与答案所在上下文的匹配数据集`am4mrqa`,而在框架中已经内置了机器阅读理解任务(`reading_comprehension`)、掩码语言模型任务(`mask_language_model`)和问答匹配任务(`answer_matching`)。这里我们希望用掩码语言模型和问答匹配任务来提升机器阅读理解任务的效果,那么我们可通过如下流程完成多任务学习的启动。
首先在config文件夹中添加训练任务相关的配置文件: 首先在config文件夹中添加训练任务相关的配置文件:
...@@ -107,7 +107,10 @@ batch_size: 4 ...@@ -107,7 +107,10 @@ batch_size: 4
in_tokens: False in_tokens: False
``` ```
而后可以在主配置文件`mtl_config.yaml`中完成多任务学习的配置,其中,使用`main_task`字段指定主任务,使用`auxilary_task`可指定辅助任务,多个辅助任务之间使用空格"` `"隔开 而后可以在主配置文件`mtl_config.yaml`中完成多任务学习的配置,其中,使用`main_task`字段指定主任务,使用`auxilary_task`可指定辅助任务,多个辅助任务之间使用空格"` `"隔开。
epoch的设定仅针对设定为主任务有效,`mix ratio`的基准值1.0也是针对主任务的训练步数而言的。例如,对于`epoch=2`,若将`reading_comprehension`任务的`mix ratio`设定为1.0,`mask_language_model``mix ratio`设定为0.5,那么`reading_comprehension`任务将训练两个完整的`epoch`,而`mask_language_model`任务的训练步数等于`reading_comprehension`训练步数的一半。
```python ```python
main_task: "reading_comprehension" main_task: "reading_comprehension"
auxiliary_task: "mask_language_model answer_matching" auxiliary_task: "mask_language_model answer_matching"
...@@ -127,8 +130,8 @@ epoch: 2 ...@@ -127,8 +130,8 @@ epoch: 2
位于`./config`目录。存放各个任务实例的配置文件,使用`yaml`格式描述。配置文件中的必选字段包括 位于`./config`目录。存放各个任务实例的配置文件,使用`yaml`格式描述。配置文件中的必选字段包括
- in_tokens:是否使用lod tensor的方式构造batch,当`in_tokens`为False时,使用padding方式构造batch。
- batch_size:每个训练或推理step所使用样本数。当`in_tokens`为True时,`batch_size`表示每个step所包含的tokens数量。 - batch_size:每个训练或推理step所使用样本数。当`in_tokens`为True时,`batch_size`表示每个step所包含的tokens数量。
- in_tokens:是否使用lod tensor的方式构造batch,当`in_tokens`为False时,使用padding方式构造batch。
训练阶段包含的必选字段包括 训练阶段包含的必选字段包括
...@@ -218,6 +221,13 @@ epoch: 2 ...@@ -218,6 +221,13 @@ epoch: 2
3. 启动多任务学习:sh run.sh 3. 启动多任务学习:sh run.sh
``` ```
## 框架结构与运行原理
框架结构如图所示
![框架图](https://tva1.sinaimg.cn/large/006y8mN6ly1g7goo0bjzwj31c20om13h.jpg)
其中`mtl_config.yaml`用于配置多任务主控的参数设定,每个任务实例的配置由用户完成后放置于`config`文件夹中。当用户运行`run.sh`后,脚本启动多任务学习控制器,控制器开始解析`mtl_config.yaml`和各个任务实例的配置文件,进而创建backbone、为各个任务创建reader和任务层,最后控制器启动训练任务,实现多任务训练。
## License ## License
This tutorial is contributed by [PaddlePaddle](https://github.com/PaddlePaddle/Paddle) and licensed under the [Apache-2.0 license](https://github.com/PaddlePaddle/models/blob/develop/LICENSE). This tutorial is contributed by [PaddlePaddle](https://github.com/PaddlePaddle/Paddle) and licensed under the [Apache-2.0 license](https://github.com/PaddlePaddle/models/blob/develop/LICENSE).
......
...@@ -31,6 +31,5 @@ max_seq_len: 512 ...@@ -31,6 +31,5 @@ max_seq_len: 512
use_ema: True use_ema: True
ema_decay: 0.9999 ema_decay: 0.9999
random_seed: 0 random_seed: 0
use_fp16: False
loss_scaling: 1.0 loss_scaling: 1.0
...@@ -275,14 +275,14 @@ def train(multitask_config): ...@@ -275,14 +275,14 @@ def train(multitask_config):
exe, exe,
args.pretrain_model_path, args.pretrain_model_path,
main_program=startup_prog, main_program=startup_prog,
use_fp16=args.use_fp16) use_fp16=False)
if args.checkpoint_path: if args.checkpoint_path:
if os.path.exists(args.checkpoint_path): if os.path.exists(args.checkpoint_path):
init_checkpoint( init_checkpoint(
exe, exe,
args.checkpoint_path, args.checkpoint_path,
main_program=startup_prog, main_program=startup_prog,
use_fp16=args.use_fp16) use_fp16=False)
else: else:
os.makedirs(args.checkpoint_path) os.makedirs(args.checkpoint_path)
...@@ -294,7 +294,7 @@ def train(multitask_config): ...@@ -294,7 +294,7 @@ def train(multitask_config):
exe, exe,
args.checkpoint_path, args.checkpoint_path,
main_program=test_prog, main_program=test_prog,
use_fp16=args.use_fp16) use_fp16=False)
if args.do_train: if args.do_train:
print('start training...') print('start training...')
......
...@@ -19,8 +19,6 @@ from __future__ import print_function ...@@ -19,8 +19,6 @@ from __future__ import print_function
import numpy as np import numpy as np
import paddle.fluid as fluid import paddle.fluid as fluid
from utils.fp16 import create_master_params_grads, master_param_to_train_param
def linear_warmup_decay(learning_rate, warmup_steps, num_train_steps): def linear_warmup_decay(learning_rate, warmup_steps, num_train_steps):
""" Applies linear warmup of learning rate from 0 and decay to 0.""" """ Applies linear warmup of learning rate from 0 and decay to 0."""
...@@ -73,8 +71,6 @@ def optimization(loss, programs, args): ...@@ -73,8 +71,6 @@ def optimization(loss, programs, args):
clip_norm_thres = 1.0 clip_norm_thres = 1.0
# When using mixed precision training, scale the gradient clip threshold # When using mixed precision training, scale the gradient clip threshold
# by loss_scaling # by loss_scaling
if args.use_fp16 and args.loss_scaling > 1.0:
clip_norm_thres *= args.loss_scaling
fluid.clip.set_gradient_clip( fluid.clip.set_gradient_clip(
clip=fluid.clip.GradientClipByGlobalNorm(clip_norm=clip_norm_thres)) clip=fluid.clip.GradientClipByGlobalNorm(clip_norm=clip_norm_thres))
...@@ -89,44 +85,19 @@ def optimization(loss, programs, args): ...@@ -89,44 +85,19 @@ def optimization(loss, programs, args):
param_list = dict() param_list = dict()
if args.use_fp16: for param in train_program.global_block().all_parameters():
param_grads = optimizer.backward(loss) param_list[param.name] = param * 1.0
master_param_grads = create_master_params_grads( param_list[param.name].stop_gradient = True
param_grads, train_program, startup_prog, args.loss_scaling)
_, param_grads = optimizer.minimize(loss)
for param, _ in master_param_grads:
param_list[param.name] = param * 1.0 if args.weight_decay > 0:
param_list[param.name].stop_gradient = True for param, grad in param_grads:
if exclude_from_weight_decay(param.name):
optimizer.apply_gradients(master_param_grads) continue
with param.block.program._optimized_guard(
if args.weight_decay > 0: [param, grad]), fluid.framework.name_scope("weight_decay"):
for param, grad in master_param_grads: updated_param = param - param_list[
if exclude_from_weight_decay(param.name.rstrip(".master")): param.name] * args.weight_decay * scheduled_lr
continue fluid.layers.assign(output=param, input=updated_param)
with param.block.program._optimized_guard(
[param, grad]), fluid.framework.name_scope("weight_decay"):
updated_param = param - param_list[
param.name] * weight_decay * scheduled_lr
fluid.layers.assign(output=param, input=updated_param)
master_param_to_train_param(master_param_grads, param_grads,
train_program)
else:
for param in train_program.global_block().all_parameters():
param_list[param.name] = param * 1.0
param_list[param.name].stop_gradient = True
_, param_grads = optimizer.minimize(loss)
if args.weight_decay > 0:
for param, grad in param_grads:
if exclude_from_weight_decay(param.name):
continue
with param.block.program._optimized_guard(
[param, grad]), fluid.framework.name_scope("weight_decay"):
updated_param = param - param_list[
param.name] * args.weight_decay * scheduled_lr
fluid.layers.assign(output=param, input=updated_param)
...@@ -25,9 +25,6 @@ def compute_loss(output_tensors, args=None): ...@@ -25,9 +25,6 @@ def compute_loss(output_tensors, args=None):
logits=logits, label=labels, return_softmax=True) logits=logits, label=labels, return_softmax=True)
loss = fluid.layers.mean(x=ce_loss) loss = fluid.layers.mean(x=ce_loss)
if args.use_fp16 and args.loss_scaling > 1.0:
loss *= args.loss_scaling
return loss return loss
......
...@@ -42,7 +42,7 @@ def create_model(reader_input, base_model=None, is_training=True, args=None): ...@@ -42,7 +42,7 @@ def create_model(reader_input, base_model=None, is_training=True, args=None):
_hidden_act = config['hidden_act'] _hidden_act = config['hidden_act']
_word_emb_name = "word_embedding" _word_emb_name = "word_embedding"
_dtype = "float16" if args.use_fp16 else "float32" _dtype = "float32"
_param_initializer = fluid.initializer.TruncatedNormal( _param_initializer = fluid.initializer.TruncatedNormal(
scale=config['initializer_range']) scale=config['initializer_range'])
......
...@@ -35,8 +35,6 @@ def compute_loss(output_tensors, args=None): ...@@ -35,8 +35,6 @@ def compute_loss(output_tensors, args=None):
start_loss = _compute_single_loss(start_logits, start_positions) start_loss = _compute_single_loss(start_logits, start_positions)
end_loss = _compute_single_loss(end_logits, end_positions) end_loss = _compute_single_loss(end_logits, end_positions)
total_loss = (start_loss + end_loss) / 2.0 total_loss = (start_loss + end_loss) / 2.0
if args.use_fp16 and args.loss_scaling > 1.0:
total_loss = total_loss * args.loss_scaling
return total_loss return total_loss
......
...@@ -484,7 +484,8 @@ class InputFeatures(object): ...@@ -484,7 +484,8 @@ class InputFeatures(object):
def read_mrqa_examples(input_file, is_training, with_negative=False): def read_mrqa_examples(input_file, is_training, with_negative=False):
"""Read a MRQA json file into a list of MRQAExample.""" """Read a MRQA json file into a list of MRQAExample."""
print("loading mrqa raw data...") phase = 'training' if is_training else 'testing'
print("loading mrqa {} data...".format(phase))
with open(input_file, "r") as reader: with open(input_file, "r") as reader:
input_data = json.load(reader)["data"] input_data = json.load(reader)["data"]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册