Skip to content

Commit fe8c2d6

Browse files
smallv0221LiuChiachiFrostML
authored
Refine api docs and readme and fix baseline bug (#912)
* fix unified transformer dtype problem * fix win dtype bug * Fix plato-2 and plato-mini dtype bug * Fix plato-2 tokenization * Refine some doc * Add general k support for topk sampling * fix seed * minor fix * Fix unitransformer readme * topk kernel optimization * add unimo model and fix generate api * add 3 datasets for unimo-text * fix tokenizer bug * paddlenlp+lightseq sample * Refine api docs and readme and fix baseline bug * add shell srcipt * remove lightseq samples * minor fix * minor fix Co-authored-by: Jiaqi Liu <[email protected]> Co-authored-by: liu zhengxi <[email protected]>
1 parent 9602532 commit fe8c2d6

File tree

12 files changed

+201
-110
lines changed

12 files changed

+201
-110
lines changed

docs/data_prepare/dataset_list.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ PaddleNLP提供了以下数据集的快速读取API,实际使用时请根据
5252
| [HYP](https://pan.webis.de/semeval19/semeval19-web/) | 英文政治新闻情感分类语料 | `paddlenlp.datasets.load_dataset('hyp')` |
5353

5454
## 文本匹配
55+
| 数据集名称 | 简介 | 调用方法 |
56+
| ---- | --------- | ------ |
5557
| [CAIL2019-SCM](https://github.com/china-ai-law-challenge/CAIL2019/tree/master/scm) | 相似法律案例匹配 | `paddlenlp.datasets.load_dataset('cail2019_scm')` |
5658

5759
## 序列标注
@@ -87,6 +89,9 @@ PaddleNLP提供了以下数据集的快速读取API,实际使用时请根据
8789
| ---- | --------- | ------ |
8890
| [Poetry](https://github.com/chinese-poetry/chinese-poetry) | 中文诗歌古典文集数据| `paddlenlp.datasets.load_dataset('poetry')`|
8991
| [Couplet](https://github.com/v-zich/couplet-clean-dataset) | 中文对联数据集| `paddlenlp.datasets.load_dataset('couplet')`|
92+
| [DuReaderQG](https://github.com/PaddlePaddle/Research/tree/master/NLP/DuReader-Robust-BASELINE) | 基于DuReader的问题生成数据集| `paddlenlp.datasets.load_dataset('dureader_qg')`|
93+
| [AdvertiseGen](https://github.com/ZhihongShao/Planning-based-Hierarchical-Variational-Model) | 中文文案生成数据集| `paddlenlp.datasets.load_dataset('advertisegen')`|
94+
| [LCSTS_new](https://aclanthology.org/D15-1229.pdf) | 中文摘要生成数据集| `paddlenlp.datasets.load_dataset('lcsts_new')`|
9095

9196
## 语料库
9297

Lines changed: 44 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,50 @@
1-
# 千言:面向事实一致性的生成评测比赛baseline
1+
# 千言:面向事实一致性的生成评测比赛基线
22

33
## 比赛简介
44

55
自然语言生成旨在让机器能够像人一样使用自然语言进行表达和交互,它是人工智能领域重要的前沿课题,近年来受到学术界和工业界广泛关注。
66

77
随着神经网络生成模型特别是预训练语言模型的迅速发展,机器生成文本的可读性和流畅性不断提升。然而,自动生成的文本中依然经常出现不符合原文或背景的错误事实描述,这种生成的事实一致性问题是自然语言生成进行落地应用的主要障碍之一,并逐渐受到研究学者的关注。鉴于当前国内外关于事实一致性的生成评测比赛十分匮乏,为了促进自然语言生成的技术发展和实际应用,我们计划组织面向事实一致性的生成评测比赛。
88

9-
在此比赛中,我们将提供三个对事实一致性有较高要求的生成任务,包括文案生成、摘要生成和问题生成。同时,在系统评价中,我们将结合文本流畅性和事实一致性两项指标综合评估参赛生成系统的水平。通过这样的任务设定和评价方式,此评测将有助于研究者和开发者更多关注自然语言生成的事实一致性难题,并为大家提供学术交流平台,从而进一步提升自然语言生成的研究水平,推动相关技术的应用发展。
9+
[此比赛](https://aistudio.baidu.com/aistudio/competition/detail/105),我们将提供三个对事实一致性有较高要求的生成任务,包括文案生成、摘要生成和问题生成。同时,在系统评价中,我们将结合文本流畅性和事实一致性两项指标综合评估参赛生成系统的水平。通过这样的任务设定和评价方式,此评测将有助于研究者和开发者更多关注自然语言生成的事实一致性难题,并为大家提供学术交流平台,从而进一步提升自然语言生成的研究水平,推动相关技术的应用发展。
1010

1111
本比赛得到中国中文信息学会自然语言生成专业委员会(筹)支持,将在2021年11月7日首届中国自然语言生成大会(CCNLG-2021)召开评测研讨会,并在大会上对获奖团队颁奖。
1212

13+
## 模型简介
14+
本次比赛提供的基线系统,基于百度提出的ERNIE-UNIMO统一模态预训练框架。在本次比赛的三个文本生成任务中,我们基于本基线使用的模型是UNIMO-text,是基于[ERNIE-UNIMO](https://arxiv.org/pdf/2012.15409.pdf)框架在文本数据上预训练得到模型。
1315

1416
## 快速开始
1517

1618
### 数据准备
1719

18-
比赛使用三个任务数据集测试参赛系统的生成能力,包括文案生成、摘要生成和问题生成
20+
比赛使用三个任务数据集测试参赛系统的生成能力,包括文案生成(AdvertiseGen)、摘要生成(LCSTS_new)和问题生成(DuReaderQG)
1921

2022
- 文案生成根据结构化的商品信息生成合适的广告文案;
2123
- 摘要生成是为输入文档生成简洁且包含关键信息的简洁文本;
2224
- 问题生成则是根据给定段落以及答案生成适合的问题。
2325

26+
为了方便用户快速使用基线,PaddleNLP Dataset API内置了数据集,一键即可完成数据集加载,示例代码如下:
27+
28+
```python
29+
from paddlenlp.datasets import load_dataset
30+
train_ds, dev_ds = load_dataset('dureader_qg', splits=('train', 'dev'))
31+
```
32+
33+
### 代码结构说明
34+
35+
以下是本项目主要代码结构及说明:
36+
37+
```text
38+
.
39+
├── run_gen.py # 模型finetune主程序入口
40+
├── gen_utils.py # 定义参数及一些工具函数
41+
├── scripts # 三个任务的基线训练脚本
42+
└── README.md # 文档说明
43+
```
2444

2545
### 模型训练
2646

27-
运行如下命令即可在样例训练集上进行finetune,并在样例验证集上进行验证
47+
运行如下命令即可在样例训练集上进行finetune,并在样例验证集上进行验证。也可以使用./scripts目录下面的训练脚本分别启动三个任务的训练。
2848

2949
```shell
3050
# GPU启动,参数`--gpus`指定训练所用的GPU卡号,可以是单卡,也可以多卡
@@ -47,9 +67,11 @@ python -m paddle.distributed.launch --gpus "0" --log_dir ./log run_gen.py \
4767
--device=gpu
4868
```
4969

50-
其中参数释义如下
70+
关键参数释义如下
5171
- `gpus` 指示了训练所用的GPU卡号。
52-
- `dataset_name` 数据集名称,dureader_qg、advertisegen和lcsts_new分别对应问题生成、文案生成和摘要生成三个任务。
72+
- `dataset_name` 数据集名称,`dureader_qg``advertisegen``lcsts_new`分别对应问题生成、文案生成和摘要生成三个任务。
73+
- `train_file` 本地训练数据地址,数据格式必须与`dataset_name`所指数据集格式相同。
74+
- `predict_file` 本地测试数据地址,数据格式必须与`dataset_name`所指数据集格式相同。
5375
- `model_name_or_path` 指示了finetune使用的具体预训练模型,可以是PaddleNLP提供的预训练模型,或者是本地的预训练模型。如果使用本地的预训练模型,可以配置本地模型的目录地址,例如: ./checkpoints/model_xx/,目录中需包含paddle预训练模型model_state.pdparams。如果使用PaddleNLP提供的预训练模型,可以选择下面其中之一。
5476

5577
| PaddleNLP提供的预训练模型 |
@@ -68,6 +90,8 @@ python -m paddle.distributed.launch --gpus "0" --log_dir ./log run_gen.py \
6890
- `warmup_propotion` 表示学习率逐渐升高到基础学习率(即上面配置的learning_rate)所需要的迭代数占总步数的比例,最早的使用可以参考[这篇论文](https://arxiv.org/pdf/1706.02677.pdf)
6991
- `max_seq_len` 模型输入序列的最大长度。
7092
- `max_target_len` 模型训练时标签的最大长度。
93+
- `min_dec_len` 模型生成序列的最小长度。
94+
- `max_dec_len` 模型生成序列的最大长度。
7195
- `do_train` 是否进行训练。
7296
- `do_predict` 是否进行预测,在验证集上会自动评估。
7397
- `device` 表示使用的设备,从gpu和cpu中选择。
@@ -81,7 +105,6 @@ python -m paddle.distributed.launch --gpus "0" --log_dir ./log run_gen.py \
81105
├── model_8000
82106
│ ├── model_config.json
83107
│ ├── model_state.pdparams
84-
│ ├── spm.model
85108
│ ├── tokenizer_config.json
86109
│ └── vocab.txt
87110
└── ...
@@ -91,54 +114,27 @@ python -m paddle.distributed.launch --gpus "0" --log_dir ./log run_gen.py \
91114

92115
### 模型预测
93116

94-
运行如下命令即可在样例测试集上进行测试
117+
运行下方脚本可以使用训练好的模型进行预测。
95118

96119
```shell
97120
export CUDA_VISIBLE_DEVICES=0
98-
# GPU启动,预测仅支持单卡
99-
python infer.py \
100-
--model_name_or_path=./checkpoints/model_80000 \
101-
--test_data_path=./datasets/test.txt \
102-
--output_path=./predict.txt \
103-
--logging_steps=500 \
104-
--seed=2021 \
105-
--batch_size=4 \
106-
--min_dec_len=1 \
107-
--max_dec_len=64 \
108-
--num_samples=20 \
109-
--decode_strategy=sampling \
110-
--top_k=5 \
121+
python run_gen.py \
122+
--dataset_name=dureader_qg \
123+
--model_name_or_path=your_model_path \
124+
--logging_steps=100 \
125+
--batch_size=16 \
126+
--max_seq_len=512 \
127+
--max_target_len=30 \
128+
--do_predict \
129+
--max_dec_len=20 \
130+
--min_dec_len=3 \
111131
--device=gpu
112132
```
113133

114-
其中参数释义如下:
115-
- `model_name_or_path` 指示了finetune使用的具体预训练模型,可以是PaddleNLP提供的预训练模型,或者是本地的预训练模型。如果使用本地的预训练模型,可以配置本地模型的目录地址,例如: ./checkpoints/model_xx/,目录中需包含paddle预训练模型model_state.pdparams。如果使用PaddleNLP提供的预训练模型,可以选择下面其中之一。
116-
117-
| PaddleNLP提供的预训练模型 |
118-
|---------------------------------|
119-
| unified_transformer-12L-cn |
120-
| unified_transformer-12L-cn-luge |
121-
122-
- `test_data_path` 表示预测集文件路径。
123-
- `output_path` 表示预测结果的保存路径。
124-
- `logging_steps` 表示日志打印间隔。
125-
- `seed` 表示随机数生成器的种子。
126-
- `batch_size` 表示每次迭代**每张卡**上的样本数目。
127-
- `min_dec_len` 表示预测生成的句子的最小长度。
128-
- `max_dec_len` 表示预测生成的句子的最大长度。
129-
- `num_samples` 表示每条样本生成的句子的数量。对于每条样本,模型会生成`num_samples`个句子,根据每个句子的概率得分进行排序,得分最高的句子作为最终的生成结果。
130-
- `decode_strategy` 表示预测解码时采取的策略,可选"sampling"、"greedy_search"和"beam_search"之一。
131-
- `top_k` 表示采用"sampling"解码策略时,token的概率按从大到小排序,生成的token只从前`top_k`个中进行采样。
132-
- `device` 表示训练使用的设备。
133-
134-
参数详情和参数的默认值请参考`args.py`
135-
136134
程序运行结束后会将预测结果保存在`output_path`中。将预测结果准备成比赛官网要求的格式,提交评估即可得评估结果。
137135

138-
采用不同的模型在样例测试集上有如下结果
136+
Finetuned baseline的模型在各任务验证集上有如下结果(指标为BLEU-4)
139137

140-
| model_name_or_path | F1 | BLEU1 / BLEU2 | DISTINCT1 / DISTINCT2 |
138+
| model_name | LCSTS_new | DuReaderQG | AdvertiseGen |
141139
| :-----------------------------: | :---: | :-----------: | :-------------------: |
142-
| unified_transformer-12L-cn | 10.62 | 0.070 / 0.022 | 0.065 / 0.304 |
143-
| unified_transformer-12L-cn-luge | 33.11 | 0.245 / 0.157 | 0.074 / 0.238 |
144-
| ./checkpoints/model_80000 | 32.38 | 0.239 / 0.150 | 0.070 / 0.219 |
140+
| finetuned unimo-text-1.0 | 18.82 | 39.78 | 10.03 |

examples/text_generation/unimo-text/gen_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def convert_example(example,
6666
add_start_token_for_decoding=True,
6767
return_position_ids=True)
6868

69-
if 'target' in example:
69+
if 'target' in example and example['target']:
7070
tokenized_example['target'] = example['target']
7171
return tokenized_example
7272

examples/text_generation/unimo-text/run_gen.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
import paddle.nn as nn
1010
import paddle.nn.functional as F
1111
from paddlenlp.transformers import LinearDecayWithWarmup
12-
from paddle.optimizer import AdamW, SGD
13-
from paddlenlp.ops.optimizer import AdamwOptimizer
12+
from paddle.optimizer import AdamW
1413

1514
from paddlenlp.datasets import load_dataset
1615
from paddlenlp.transformers import UNIMOLMHeadModel, UNIMOTokenizer, BasicTokenizer
@@ -24,6 +23,8 @@ def parse_args():
2423
parser = argparse.ArgumentParser(__doc__)
2524
parser.add_argument('--dataset_name', type=str, default='dureader_qg', help='The name of the dataset to load.')
2625
parser.add_argument('--model_name_or_path', type=str, default='unimo-text-1.0', help='The path or shortcut name of the pre-trained model.')
26+
parser.add_argument("--train_file", type=str, required=False, default=None, help="Train data path.")
27+
parser.add_argument("--predict_file", type=str, required=False, default=None, help="Predict data path.")
2728
parser.add_argument('--save_dir', type=str, default='./checkpoints', help='The directory where the checkpoints will be saved.')
2829
parser.add_argument('--logging_steps', type=int, default=100, help='Log every X updates steps.')
2930
parser.add_argument('--save_steps', type=int, default=1000, help='Save checkpoint every X updates steps.')
@@ -103,7 +104,10 @@ def run(args):
103104
if world_size > 1:
104105
model = paddle.DataParallel(model)
105106

106-
train_ds, dev_ds = load_dataset(args.dataset_name, splits=['train', 'dev'])
107+
train_ds = load_dataset(
108+
args.dataset_name, splits='train', data_files=args.train_file)
109+
dev_ds = load_dataset(
110+
args.dataset_name, splits='dev', data_files=args.predict_file)
107111

108112
train_ds, train_data_loader = create_data_loader(train_ds, tokenizer, args,
109113
'train')
@@ -165,13 +169,18 @@ def run(args):
165169
save_ckpt(model, tokenizer, args.save_dir, step)
166170
print('Saved step {} model.\n'.format(step))
167171
if args.do_predict:
168-
evaluation(model, dev_data_loader, args, tokenizer)
172+
model_eval = model._layers if isinstance(
173+
model, paddle.DataParallel) else model
174+
evaluation(model_eval, dev_data_loader, args,
175+
tokenizer)
169176

170177
batch_start_time = time.time()
171178

172179
print('\nTraining completed.')
173180
elif args.do_predict:
174-
evaluation(model, dev_data_loader, args, tokenizer)
181+
model_eval = model._layers if isinstance(model,
182+
paddle.DataParallel) else model
183+
evaluation(model_eval, dev_data_loader, args, tokenizer)
175184

176185

177186
@paddle.no_grad()
@@ -198,8 +207,9 @@ def evaluation(model, data_loader, args, tokenizer):
198207
eos_token_id=tokenizer.mask_token_id)
199208

200209
total_time += (time.time() - start_time)
201-
if step % 100 == 0:
202-
print('step %d - %.3fs/step' % (step, total_time / 100))
210+
if step % args.logging_steps == 0:
211+
print('step %d - %.3fs/step' %
212+
(step, total_time / args.logging_steps))
203213
total_time = 0.0
204214

205215
results = select_sum(ids, scores, tokenizer, args.max_dec_len,
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# GPU启动,参数`--gpus`指定训练所用的GPU卡号,可以是单卡,也可以多卡
2+
unset CUDA_VISIBLE_DEVICES
3+
4+
log_dir=./lcsts-log
5+
rm -rf ${log_dir}
6+
mkdir -p ${log_dir}
7+
8+
python -m paddle.distributed.launch --gpus "0,1,2,3" --log_dir ${log_dir} run_gen.py \
9+
--dataset_name=lcsts_new \
10+
--model_name_or_path=unimo-text-1.0 \
11+
--save_dir=${log_dir}/checkpoints \
12+
--logging_steps=100 \
13+
--save_steps=10000 \
14+
--epochs=6 \
15+
--batch_size=64 \
16+
--learning_rate=5e-5 \
17+
--warmup_propotion=0.02 \
18+
--weight_decay=0.01 \
19+
--max_seq_len=320 \
20+
--max_target_len=30 \
21+
--max_dec_len=20 \
22+
--min_dec_len=3 \
23+
--do_train \
24+
--do_predict \
25+
--device=gpu >> ${log_dir}/lanch.log 2>&1
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# GPU启动,参数`--gpus`指定训练所用的GPU卡号,可以是单卡,也可以多卡
2+
unset CUDA_VISIBLE_DEVICES
3+
4+
log_dir=./qg-log
5+
rm -rf ${log_dir}
6+
mkdir -p ${log_dir}
7+
8+
python -m paddle.distributed.launch --gpus "0,1,2,3" --log_dir ${log_dir} run_gen.py \
9+
--dataset_name=dureader_qg \
10+
--model_name_or_path=unimo-text-1.0 \
11+
--save_dir=${log_dir}/checkpoints \
12+
--logging_steps=10 \
13+
--save_steps=1000 \
14+
--epochs=6 \
15+
--batch_size=8 \
16+
--learning_rate=5e-5 \
17+
--warmup_propotion=0.02 \
18+
--weight_decay=0.01 \
19+
--max_seq_len=320 \
20+
--max_target_len=30 \
21+
--max_dec_len=20 \
22+
--min_dec_len=3 \
23+
--do_train \
24+
--do_predict \
25+
--device=gpu >> ${log_dir}/lanch.log 2>&1
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# GPU启动,参数`--gpus`指定训练所用的GPU卡号,可以是单卡,也可以多卡
2+
unset CUDA_VISIBLE_DEVICES
3+
4+
log_dir=./table-log
5+
rm -rf ${log_dir}
6+
mkdir -p ${log_dir}
7+
8+
python -m paddle.distributed.launch --gpus "0,1,2,3" --log_dir ${log_dir} run_gen.py \
9+
--dataset_name=advertisegen \
10+
--model_name_or_path=unimo-text-1.0 \
11+
--save_dir=${log_dir}/checkpoints \
12+
--logging_steps=100 \
13+
--save_steps=1000 \
14+
--epochs=6 \
15+
--batch_size=8 \
16+
--learning_rate=5e-5 \
17+
--warmup_propotion=0.02 \
18+
--weight_decay=0.01 \
19+
--max_seq_len=500 \
20+
--max_target_len=200 \
21+
--max_dec_len=200 \
22+
--min_dec_len=10 \
23+
--do_train \
24+
--do_predict \
25+
--device=gpu >> ${log_dir}/lanch.log 2>&1

paddlenlp/datasets/advertisegen.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def _read(self, filename, *args):
6262

6363
yield {
6464
'source': json_data["content"],
65-
'target': json_data["summary"],
65+
'target': json_data.get("summary", ''),
6666
'id': data_id
6767
}
6868
data_id += 1

paddlenlp/datasets/dureader_qg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def _read(self, filename, *args):
6262

6363
yield {
6464
'source': json_data["context"],
65-
'target': json_data["question"],
65+
'target': json_data.get("question", ''),
6666
'title': title,
6767
'id': json_data['id']
6868
}

paddlenlp/datasets/lcsts_new.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,6 @@ def _read(self, filename, *args):
6262

6363
yield {
6464
'source': json_data["content"],
65-
'target': json_data["summary"],
65+
'target': json_data.get("summary", ''),
6666
'id': json_data['id']
6767
}

0 commit comments

Comments
 (0)