test_trt_convert_rnn.py 12.4 KB
Newer Older
Z
zhoutianzi666 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# Copyright (c) 2022 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.

15 16
import os
import unittest
Z
zhoutianzi666 已提交
17
from functools import partial
18
from typing import List
19 20 21 22 23 24

import numpy as np
from program_config import ProgramConfig, TensorConfig
from trt_layer_auto_scan_test import TrtLayerAutoScanTest

import paddle.inference as paddle_infer
Z
zhoutianzi666 已提交
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39


class TrtConvertSliceTest(TrtLayerAutoScanTest):
    def is_program_valid(self, program_config: ProgramConfig) -> bool:
        return True

    def sample_program_configs(self):
        self.trt_param.workspace_size = 1073741824
        for hidden_size in [30]:
            for input_size in [30]:
                for batch in [2]:
                    for seq_len in [5]:
                        for num_layers in [1, 2]:
                            for is_bidirec in [True, False]:
                                dics = []
40 41 42 43 44 45 46 47 48 49 50 51 52 53
                                dics.append(
                                    {
                                        "hidden_size": hidden_size,
                                        "input_size": input_size,
                                        "num_layers": num_layers,
                                        "mode": "LSTM",
                                        "is_bidirec": is_bidirec,
                                        "is_test": True,
                                        "dropout_prob": 0.0,
                                        # for my convience
                                        "batch": batch,
                                        "seq_len": seq_len,
                                    }
                                )
Z
zhoutianzi666 已提交
54 55

                                K = 1
56
                                if dics[0]["is_bidirec"]:
Z
zhoutianzi666 已提交
57 58 59
                                    K = 2

                                def generate_input1():
60 61 62 63 64 65 66
                                    return (
                                        np.random.random(
                                            [batch, seq_len, input_size]
                                        ).astype(np.float32)
                                        * 2
                                        - 1
                                    )
Z
zhoutianzi666 已提交
67 68 69

                                # initial input -> hidden
                                def generate_w0():
70 71 72 73 74 75 76
                                    return (
                                        np.random.random(
                                            [4 * hidden_size, input_size]
                                        ).astype(np.float32)
                                        * 2
                                        - 1
                                    )
Z
zhoutianzi666 已提交
77 78 79

                                # prev layer's output -> hidden
                                def generate_w1():
80 81 82 83 84 85 86
                                    return (
                                        np.random.random(
                                            [4 * hidden_size, K * hidden_size]
                                        ).astype(np.float32)
                                        * 2
                                        - 1
                                    )
Z
zhoutianzi666 已提交
87 88 89

                                #
                                def generate_w2():
90 91 92 93 94 95 96
                                    return (
                                        np.random.random(
                                            [4 * hidden_size, hidden_size]
                                        ).astype(np.float32)
                                        * 2
                                        - 1
                                    )
Z
zhoutianzi666 已提交
97 98

                                def generate_b():
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
                                    return (
                                        np.random.random(
                                            [4 * hidden_size]
                                        ).astype(np.float32)
                                        * 2
                                        - 1
                                    )

                                dics.append(
                                    {
                                        "dtype": 5,
                                        "input_dim_idx": 0,
                                        "str_value": "",
                                        "value": 0.0,
                                        "shape": [
                                            K * num_layers,
                                            -1,
                                            hidden_size,
                                        ],
                                        "output_dim_idx": 1,
                                    }
                                )
Z
zhoutianzi666 已提交
121 122 123 124
                                dics.append({"axis": [1, 0, 2]})
                                # set  weights
                                WeightList = [
                                    "weight" + str(i)
125 126 127
                                    for i in range(
                                        4 * K * dics[0]["num_layers"]
                                    )
Z
zhoutianzi666 已提交
128 129 130 131 132
                                ]
                                weights = {}
                                for i in range((int)(len(WeightList) / 2)):
                                    # mean this weight : input->hidden
                                    # input has 2 case: initial input input_size, K * hidden form the prev layer.
133 134
                                    if i % 2 == 0:
                                        if i <= K:
Z
zhoutianzi666 已提交
135
                                            weights[
136 137 138 139
                                                WeightList[i]
                                            ] = TensorConfig(
                                                data_gen=partial(generate_w0)
                                            )
Z
zhoutianzi666 已提交
140 141
                                        else:
                                            weights[
142 143 144 145
                                                WeightList[i]
                                            ] = TensorConfig(
                                                data_gen=partial(generate_w1)
                                            )
Z
zhoutianzi666 已提交
146
                                    # mean this weight : hidden->hidden
147
                                    if i % 2 == 1:
Z
zhoutianzi666 已提交
148
                                        weights[WeightList[i]] = TensorConfig(
149 150 151 152 153
                                            data_gen=partial(generate_w2)
                                        )
                                for i in range(
                                    (int)(len(WeightList) / 2), len(WeightList)
                                ):
Z
zhoutianzi666 已提交
154
                                    weights[WeightList[i]] = TensorConfig(
155 156
                                        data_gen=partial(generate_b)
                                    )
Z
zhoutianzi666 已提交
157 158
                                ops_config = [
                                    {
159 160 161 162
                                        "op_type": "fill_constant_batch_size_like",
                                        "op_inputs": {"Input": ["input_data"]},
                                        "op_outputs": {"Out": ["prestate1"]},
                                        "op_attrs": dics[1],
Z
zhoutianzi666 已提交
163 164
                                    },
                                    {
165 166 167 168
                                        "op_type": "fill_constant_batch_size_like",
                                        "op_inputs": {"Input": ["input_data"]},
                                        "op_outputs": {"Out": ["prestate2"]},
                                        "op_attrs": dics[1],
Z
zhoutianzi666 已提交
169 170 171
                                    },
                                    {
                                        "op_type": "transpose2",
172
                                        "op_inputs": {"X": ["input_data"]},
Z
zhoutianzi666 已提交
173 174 175
                                        "op_outputs": {
                                            "Out": ["rnn_input_data"]
                                        },
176
                                        "op_attrs": dics[2],
Z
zhoutianzi666 已提交
177 178 179 180 181 182
                                    },
                                    {
                                        "op_type": "rnn",
                                        "op_inputs": {
                                            "Input": ["rnn_input_data"],
                                            # prev_c, prev_h
183 184 185 186
                                            "PreState": [
                                                "prestate1",
                                                "prestate2",
                                            ],
Z
zhoutianzi666 已提交
187 188 189 190 191 192
                                            "WeightList": WeightList,
                                        },
                                        "op_outputs": {
                                            "Out": ["rnn_output_data"],
                                            "State": [
                                                "state_output_data0",
193
                                                "state_output_data1",
Z
zhoutianzi666 已提交
194 195
                                            ],
                                            "Reserve": ["reserve_data"],
196 197 198
                                            "DropoutState": [
                                                "DropoutState_data"
                                            ],
Z
zhoutianzi666 已提交
199
                                        },
200 201
                                        "op_attrs": dics[0],
                                    },
Z
zhoutianzi666 已提交
202 203 204 205 206 207 208
                                ]
                                ops = self.generate_op_config(ops_config)

                                program_config = ProgramConfig(
                                    ops=ops,
                                    weights=weights,
                                    inputs={
209 210 211
                                        "input_data": TensorConfig(
                                            data_gen=partial(generate_input1)
                                        )
Z
zhoutianzi666 已提交
212
                                    },
213 214
                                    outputs=["rnn_output_data"],
                                )
Z
zhoutianzi666 已提交
215 216 217 218

                                yield program_config

    def sample_predictor_configs(
219 220
        self, program_config
    ) -> (paddle_infer.Config, List[int], float):
Z
zhoutianzi666 已提交
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
        attrs = [
            program_config.ops[i].attrs for i in range(len(program_config.ops))
        ]
        num_layers = attrs[3]["num_layers"]
        hidden_size = attrs[3]["hidden_size"]
        batch = attrs[3]["batch"]
        input_size = attrs[3]["input_size"]
        seq_len = attrs[3]["seq_len"]

        K = 1
        if attrs[3]["is_bidirec"]:
            K = 2

        def generate_dynamic_shape(attrs):
            self.dynamic_shape.min_input_shape = {
                "input_data": [batch - 1, seq_len, input_size],
            }
            self.dynamic_shape.max_input_shape = {
                "input_data": [batch + 1, seq_len, input_size],
            }
            self.dynamic_shape.opt_input_shape = {
                "input_data": [batch, seq_len, input_size],
            }

        def clear_dynamic_shape():
            self.dynamic_shape.min_input_shape = {}
            self.dynamic_shape.max_input_shape = {}
            self.dynamic_shape.opt_input_shape = {}

        def generate_trt_nodes_num(attrs, dynamic_shape):
            return 1, 2

        attrs = [
            program_config.ops[i].attrs for i in range(len(program_config.ops))
        ]

        # The output has diff between gpu and trt in PR-CI-Windows-Inference
        tol_fp32 = 1e-5
        tol_half = 1e-2
260
        if os.name == 'nt':
Z
zhoutianzi666 已提交
261 262 263 264 265 266 267
            tol_fp32 = 1e-2
            tol_half = 1e-1

        # for dynamic_shape
        generate_dynamic_shape(attrs)
        self.trt_param.precision = paddle_infer.PrecisionType.Float32
        yield self.create_inference_config(), generate_trt_nodes_num(
268 269
            attrs, True
        ), tol_fp32
Z
zhoutianzi666 已提交
270 271
        self.trt_param.precision = paddle_infer.PrecisionType.Half
        yield self.create_inference_config(), generate_trt_nodes_num(
272 273
            attrs, True
        ), tol_half
Z
zhoutianzi666 已提交
274 275 276 277 278 279 280

    def test(self):
        self.run_test()


if __name__ == "__main__":
    unittest.main()