wmt14.py 6.2 KB
Newer Older
H
Helin Wang 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Q
qijun 已提交
15
WMT14 dataset.
Q
qijun 已提交
16 17
The original WMT14 dataset is too large and a small set of data for set is
provided. This module will download dataset from
18
http://paddlepaddle.bj.bcebos.com/demo/wmt_shrinked_data/wmt14.tgz and
Q
qijun 已提交
19
parse training set and test set into paddle reader creators.
Q
qijun 已提交
20

H
Helin Wang 已提交
21
"""
22 23 24

from __future__ import print_function

25
import six
Q
qiaolongfei 已提交
26
import tarfile
L
Luo Tao 已提交
27
import gzip
Q
qiaolongfei 已提交
28

29
import paddle.dataset.common
M
minqiyang 已提交
30
import paddle.compat as cpt
31
import paddle.utils.deprecated as deprecated
H
Helin Wang 已提交
32

33 34
__all__ = []

Y
ying 已提交
35 36
URL_DEV_TEST = ('http://www-lium.univ-lemans.fr/~schwenk/'
                'cslm_joint_paper/data/dev+test.tgz')
H
Helin Wang 已提交
37
MD5_DEV_TEST = '7d7897317ddd8ba0ae5c5fa7248d3ff5'
Y
ying 已提交
38 39
# this is a small set of data for test. The original data is too large and
# will be add later.
L
luotao1 已提交
40
URL_TRAIN = ('http://paddlemodels.bj.bcebos.com/wmt/wmt14.tgz')
L
Luo Tao 已提交
41
MD5_TRAIN = '0791583d57d5beb693b9414c5b36798c'
42
# BLEU of this trained model is 26.92
T
typhoonzero 已提交
43
URL_MODEL = 'http://paddlemodels.bj.bcebos.com/wmt%2Fwmt14.tgz'
44
MD5_MODEL = '0cb4a5366189b6acba876491c8724fa3'
Q
qiaolongfei 已提交
45 46 47 48 49 50

START = "<s>"
END = "<e>"
UNK = "<unk>"
UNK_IDX = 2

Q
qiaolongfei 已提交
51

Y
ying 已提交
52 53
def __read_to_dict(tar_file, dict_size):
    def __to_dict(fd, size):
Q
qiaolongfei 已提交
54
        out_dict = dict()
Q
qiaolongfei 已提交
55 56
        for line_count, line in enumerate(fd):
            if line_count < size:
M
minqiyang 已提交
57
                out_dict[cpt.to_text(line.strip())] = line_count
Q
qiaolongfei 已提交
58 59
            else:
                break
Q
qiaolongfei 已提交
60 61 62 63 64 65 66 67
        return out_dict

    with tarfile.open(tar_file, mode='r') as f:
        names = [
            each_item.name for each_item in f
            if each_item.name.endswith("src.dict")
        ]
        assert len(names) == 1
Y
ying 已提交
68
        src_dict = __to_dict(f.extractfile(names[0]), dict_size)
Q
qiaolongfei 已提交
69 70 71 72 73
        names = [
            each_item.name for each_item in f
            if each_item.name.endswith("trg.dict")
        ]
        assert len(names) == 1
Y
ying 已提交
74
        trg_dict = __to_dict(f.extractfile(names[0]), dict_size)
Q
qiaolongfei 已提交
75 76 77 78 79
        return src_dict, trg_dict


def reader_creator(tar_file, file_name, dict_size):
    def reader():
Y
ying 已提交
80
        src_dict, trg_dict = __read_to_dict(tar_file, dict_size)
Q
qiaolongfei 已提交
81 82 83 84
        with tarfile.open(tar_file, mode='r') as f:
            names = [
                each_item.name for each_item in f
                if each_item.name.endswith(file_name)
H
Helin Wang 已提交
85
            ]
Q
qiaolongfei 已提交
86 87
            for name in names:
                for line in f.extractfile(name):
M
minqiyang 已提交
88 89
                    line = cpt.to_text(line)
                    line_split = line.strip().split('\t')
Q
qiaolongfei 已提交
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
                    if len(line_split) != 2:
                        continue
                    src_seq = line_split[0]  # one source sequence
                    src_words = src_seq.split()
                    src_ids = [
                        src_dict.get(w, UNK_IDX)
                        for w in [START] + src_words + [END]
                    ]

                    trg_seq = line_split[1]  # one target sequence
                    trg_words = trg_seq.split()
                    trg_ids = [trg_dict.get(w, UNK_IDX) for w in trg_words]

                    # remove sequence whose length > 80 in training mode
                    if len(src_ids) > 80 or len(trg_ids) > 80:
                        continue
                    trg_ids_next = trg_ids + [trg_dict[END]]
                    trg_ids = [trg_dict[START]] + trg_ids

                    yield src_ids, trg_ids, trg_ids_next

    return reader


114 115 116
@deprecated(
    since="2.0.0",
    update_to="paddle.text.datasets.WMT14",
117
    level=1,
118
    reason="Please use new dataset API which supports paddle.io.DataLoader")
Q
qiaolongfei 已提交
119
def train(dict_size):
Q
qijun 已提交
120
    """
Q
qijun 已提交
121
    WMT14 training set creator.
Q
qijun 已提交
122

Q
qijun 已提交
123 124 125
    It returns a reader creator, each sample in the reader is source language
    word ID sequence, target language word ID sequence and next word ID
    sequence.
Q
qijun 已提交
126

Q
qijun 已提交
127
    :return: Training reader creator
Q
qijun 已提交
128 129
    :rtype: callable
    """
Q
qiaolongfei 已提交
130
    return reader_creator(
131
        paddle.dataset.common.download(URL_TRAIN, 'wmt14', MD5_TRAIN),
R
root 已提交
132
        'train/train', dict_size)
Q
qiaolongfei 已提交
133 134


135 136 137
@deprecated(
    since="2.0.0",
    update_to="paddle.text.datasets.WMT14",
138
    level=1,
139
    reason="Please use new dataset API which supports paddle.io.DataLoader")
Q
qiaolongfei 已提交
140
def test(dict_size):
Q
qijun 已提交
141 142 143
    """
    WMT14 test set creator.

Q
qijun 已提交
144 145 146
    It returns a reader creator, each sample in the reader is source language
    word ID sequence, target language word ID sequence and next word ID
    sequence.
Q
qijun 已提交
147

Q
qijun 已提交
148
    :return: Test reader creator
Q
qijun 已提交
149 150
    :rtype: callable
    """
Q
qiaolongfei 已提交
151
    return reader_creator(
152
        paddle.dataset.common.download(URL_TRAIN, 'wmt14', MD5_TRAIN),
R
root 已提交
153
        'test/test', dict_size)
Y
Yancey1989 已提交
154 155


156 157 158
@deprecated(
    since="2.0.0",
    update_to="paddle.text.datasets.WMT14",
159
    level=1,
160
    reason="Please use new dataset API which supports paddle.io.DataLoader")
L
Luo Tao 已提交
161 162
def gen(dict_size):
    return reader_creator(
163
        paddle.dataset.common.download(URL_TRAIN, 'wmt14', MD5_TRAIN),
R
root 已提交
164
        'gen/gen', dict_size)
L
Luo Tao 已提交
165 166


167 168 169
@deprecated(
    since="2.0.0",
    update_to="paddle.text.datasets.WMT14",
170
    level=1,
171
    reason="Please use new dataset API which supports paddle.io.DataLoader")
L
Luo Tao 已提交
172 173 174
def get_dict(dict_size, reverse=True):
    # if reverse = False, return dict = {'a':'001', 'b':'002', ...}
    # else reverse = true, return dict = {'001':'a', '002':'b', ...}
175
    tar_file = paddle.dataset.common.download(URL_TRAIN, 'wmt14', MD5_TRAIN)
Y
ying 已提交
176
    src_dict, trg_dict = __read_to_dict(tar_file, dict_size)
L
Luo Tao 已提交
177
    if reverse:
M
minqiyang 已提交
178 179
        src_dict = {v: k for k, v in six.iteritems(src_dict)}
        trg_dict = {v: k for k, v in six.iteritems(trg_dict)}
L
Luo Tao 已提交
180
    return src_dict, trg_dict
L
Luo Tao 已提交
181 182


183 184 185
@deprecated(
    since="2.0.0",
    update_to="paddle.text.datasets.WMT14",
186
    level=1,
187
    reason="Please use new dataset API which supports paddle.io.DataLoader")
188
def fetch():
189 190
    paddle.dataset.common.download(URL_TRAIN, 'wmt14', MD5_TRAIN)
    paddle.dataset.common.download(URL_MODEL, 'wmt14', MD5_MODEL)