test_latency_predictor.py 15.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
# Copyright (c) 2019  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.
import sys, os
sys.path.append("../")
import unittest
import paddle
import paddleslim
from paddleslim.analysis import LatencyPredictor, TableLatencyPredictor
Z
zhouzj 已提交
20
from paddleslim.analysis._utils import opt_model, save_cls_model, save_det_model
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38


def channel_shuffle(x, groups):
    batch_size, num_channels, height, width = x.shape[0:4]
    channels_per_group = num_channels // groups

    x = paddle.reshape(
        x=x, shape=[batch_size, groups, channels_per_group, height, width])

    x = paddle.transpose(x=x, perm=[0, 2, 1, 3, 4])

    x = paddle.reshape(x=x, shape=[batch_size, num_channels, height, width])
    return x


class ModelCase1(paddle.nn.Layer):
    def __init__(self):
        super(ModelCase1, self).__init__()
W
whs 已提交
39 40
        self.conv1 = paddle.nn.Conv2D(58, 58, 1)
        self.conv2 = paddle.nn.Conv2D(58, 58, 1)
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55

    def forward(self, inputs):
        x1, x2 = paddle.split(
            inputs,
            num_or_sections=[inputs.shape[1] // 2, inputs.shape[1] // 2],
            axis=1)
        x1 = self.conv1(x1)
        x2 = self.conv2(x2)
        out = paddle.concat([x1, x2], axis=1)
        return channel_shuffle(out, 2)


class ModelCase2(paddle.nn.Layer):
    def __init__(self):
        super(ModelCase2, self).__init__()
W
whs 已提交
56
        self.conv1 = paddle.nn.Conv2D(3, 24, 3, stride=2, padding=1)
57 58 59 60 61 62 63 64 65 66

    def forward(self, inputs):
        image = inputs['image']

        return self.conv1(image)


class ModelCase3(paddle.nn.Layer):
    def __init__(self):
        super(ModelCase3, self).__init__()
W
whs 已提交
67
        self.conv1 = paddle.nn.Conv2D(3, 24, 3, stride=2, padding=1)
68 69 70 71 72 73 74 75 76 77 78 79

    def forward(self, inputs):
        image = inputs['image']
        im_shape = inputs['im_shape']
        scale_factor = inputs['scale_factor']

        return self.conv1(image), im_shape, scale_factor


class ModelCase4(paddle.nn.Layer):
    def __init__(self):
        super(ModelCase4, self).__init__()
W
whs 已提交
80 81 82
        self.bn1 = paddle.nn.BatchNorm2D(3)
        self.ln1 = paddle.nn.LayerNorm([3 * 16 * 16])
        self.relu1 = paddle.nn.ReLU()
83 84 85 86 87 88 89
        self.fc1 = paddle.nn.Linear(3 * 16 * 16, 3 * 16 * 16)

    def forward(self, inputs):
        x = self.bn1(inputs)
        x = paddle.reshape(x, [1, 3 * 16 * 16])
        x = self.ln1(x)
        x = self.fc1(x)
W
whs 已提交
90
        x = paddle.unsqueeze(x=x, axis=[2])
91
        x = self.relu1(x)
W
whs 已提交
92
        y = paddle.full(shape=x.shape, fill_value=1)
93 94 95
        x = paddle.stack([x, y], axis=3)
        x = paddle.slice(x, axes=[0], starts=[0], ends=[1])
        x = paddle.exp(x)
W
whs 已提交
96
        y += paddle.uniform(y.shape)
W
whs 已提交
97
        y = paddle.mean(x=y, axis=1, keepdim=True)
98
        return paddle.greater_equal(x, y)
99 100 101 102 103


class ModelCase5(paddle.nn.Layer):
    def __init__(self):
        super(ModelCase5, self).__init__()
W
whs 已提交
104
        self.bn1 = paddle.nn.BatchNorm2D(255)
105 106 107 108

    def forward(self, inputs):
        image = inputs['image']
        image = self.bn1(image)
W
whs 已提交
109
        img_size = paddle.static.data(
Z
zhouzj 已提交
110
            name='img_size', shape=[None, 2], dtype='int32')
111
        anchors = [10, 13, 16, 30, 33, 23]
W
whs 已提交
112
        boxes, scores = paddle.vision.ops.yolo_box(
113 114 115 116 117 118
            x=image,
            img_size=img_size,
            class_num=80,
            anchors=anchors,
            conf_thresh=0.01,
            downsample_ratio=32)
119
        out = paddle.vision.ops.matrix_nms(
120 121 122 123 124 125 126 127
            bboxes=boxes,
            scores=scores,
            background_label=0,
            score_threshold=0.5,
            post_threshold=0.1,
            nms_top_k=400,
            keep_top_k=200,
            normalized=False)
128
        box, var = paddle.vision.ops.prior_box(
129 130 131 132
            input=image, image=image, min_sizes=[2.], clip=True, flip=True)
        return boxes, scores, box, var, out


133 134 135
class ModelCase6(paddle.nn.Layer):
    def __init__(self):
        super(ModelCase6, self).__init__()
W
whs 已提交
136 137
        self.bn1 = paddle.nn.BatchNorm2D(3)
        self.relu1 = paddle.nn.ReLU()
138 139
        self.fc1 = paddle.nn.Linear(3 * 16 * 16, 3 * 16 * 16)
        self.dp = paddle.nn.Dropout(p=0.5)
140 141
        self.lstm = paddle.nn.LSTM(
            1536, 10, direction='bidirectional', num_layers=2)
142 143 144 145 146

    def forward(self, inputs):
        x = self.bn1(inputs)
        x = paddle.reshape(x, [1, 3 * 16 * 16])
        x = self.fc1(x)
W
whs 已提交
147
        x = paddle.unsqueeze(x=x, axis=[2])
148
        x = self.relu1(x)
W
whs 已提交
149
        y = paddle.full(shape=x.shape, fill_value=1)
150
        # x = paddle.stack([x, y], axis=3)
151 152
        x = paddle.slice(x, axes=[0], starts=[0], ends=[1])
        x = paddle.exp(x)
153
        # y += paddle.fluid.layers.uniform_random(y.shape)
154 155 156 157 158 159
        y = paddle.expand(y, shape=[1, 768, 768, 2])
        x = paddle.expand(x, shape=[1, 768, 768, 2])
        out = paddle.concat([x, y])
        out = self.dp(out)
        out = channel_shuffle(out, 2)
        out1, out2 = paddle.split(out, num_or_sections=2, axis=1)
160 161 162 163 164 165 166 167
        outshape = out1.shape
        max_idx = paddle.argmax(
            out1.reshape((outshape[0], outshape[1], outshape[2] * outshape[3])),
            axis=-1)
        out2 = out2.reshape(
            (outshape[0], outshape[1], outshape[2] * outshape[3]))
        res, _ = self.lstm(out2)
        return res, max_idx
168 169 170 171 172


class ModelCase7(paddle.nn.Layer):
    def __init__(self):
        super(ModelCase7, self).__init__()
W
whs 已提交
173
        self.bn1 = paddle.nn.BatchNorm2D(255)
174 175 176 177

    def forward(self, inputs):
        image = inputs['image']
        image = self.bn1(image)
W
whs 已提交
178
        img_size = paddle.static.data(
Z
zhouzj 已提交
179
            name='img_size', shape=[None, 2], dtype='int32')
180
        anchors = [10, 13, 16, 30, 33, 23]
W
whs 已提交
181
        boxes, scores = paddle.vision.ops.yolo_box(
182 183 184 185 186 187
            x=image,
            img_size=img_size,
            class_num=80,
            anchors=anchors,
            conf_thresh=0.01,
            downsample_ratio=32)
188
        box, var = paddle.vision.ops.prior_box(
189 190 191 192
            input=image, image=image, min_sizes=[2.], clip=True, flip=True)
        return boxes, scores, box, var


Z
zhouzj 已提交
193 194 195 196 197 198 199 200 201 202 203
class TestCase(unittest.TestCase):
    def setUp(slef):
        os.system(
            'wget -q https://bj.bcebos.com/v1/paddle-slim-models/LatencyPredictor/test_mobilenetv1.tar'
        )
        os.system('tar -xf test_mobilenetv1.tar')
        os.system(
            'wget -q https://bj.bcebos.com/v1/paddle-slim-models/LatencyPredictor/test_mobilenetv1_qat.tar'
        )
        os.system('tar -xf test_mobilenetv1_qat.tar')

204 205
    def test_case1(self):
        paddle.disable_static()
206
        predictor = TableLatencyPredictor(table_file='SD710')
Z
zhouzj 已提交
207 208
        model_file = 'test_mobilenetv1/inference.pdmodel'
        param_file = 'test_mobilenetv1/inference.pdiparams'
209 210
        latency = predictor.predict(
            model_file=model_file, param_file=param_file, data_type='fp32')
Z
zhouzj 已提交
211
        assert latency > 0
212

Z
zhouzj 已提交
213 214
        model_file = 'test_mobilenetv1_qat/inference.pdmodel'
        param_file = 'test_mobilenetv1_qat/inference.pdiparams'
215 216
        latency = predictor.predict(
            model_file=model_file, param_file=param_file, data_type='int8')
217 218 219 220
        assert latency > 0


class TestCase2(unittest.TestCase):
Z
zhouzj 已提交
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 260 261 262 263 264 265 266 267 268 269 270 271 272
    def setUp(slef):
        os.system(
            'wget -q https://bj.bcebos.com/v1/paddle-slim-models/LatencyPredictor/test_mobilenetv2.tar'
        )
        os.system('tar -xf test_mobilenetv2.tar')
        os.system(
            'wget -q https://bj.bcebos.com/v1/paddle-slim-models/LatencyPredictor/test_mobilenetv2_qat.tar'
        )
        os.system('tar -xf test_mobilenetv2_qat.tar')

    def _infer_shape(self, model_dir, model_filename, params_filename,
                     input_shapes, save_path):
        assert type(input_shapes) in [
            dict, list, tuple
        ], f'Type of input_shapes should be in [dict, tuple or list] but got {type(input_shapes)}.'
        paddle.enable_static()
        exe = paddle.static.Executor(paddle.CPUPlace())

        model_name = '.'.join(model_filename.split('.')[:-1])
        model_path_prefix = os.path.join(model_dir, model_name)
        [inference_program, feed_target_names, fetch_targets] = (
            paddle.static.load_inference_model(
                path_prefix=model_path_prefix, executor=exe))

        if type(input_shapes) in [list, tuple]:
            assert len(
                feed_target_names
            ) == 1, f"The number of model's inputs should be 1 but got {feed_target_names}."
            input_shapes = {feed_target_names[0]: input_shapes}

        feed_vars = []
        for var_ in inference_program.list_vars():
            if var_.name in feed_target_names:
                feed_vars.append(var_)
                var_.desc.set_shape(input_shapes[var_.name])

        for block in inference_program.blocks:
            for op in block.ops:
                if op.type not in ["feed", "fetch"]:
                    op.desc.infer_shape(block.desc)

        save_path = os.path.join(save_path, "infered_shape")
        os.makedirs(save_path)
        paddle.static.save_inference_model(
            save_path,
            feed_vars,
            fetch_targets,
            exe,
            program=inference_program,
            clip_extra=False)
        print(f"Saved model infered shape to {save_path}")

273
    def test_case2(self):
274
        predictor = TableLatencyPredictor(table_file='SD710')
Z
zhouzj 已提交
275 276
        model_file = 'test_mobilenetv2/inference.pdmodel'
        param_file = 'test_mobilenetv2/inference.pdiparams'
277 278
        latency = predictor.predict(
            model_file=model_file, param_file=param_file, data_type='fp32')
279 280
        assert latency > 0

281 282 283 284 285 286
        pbmodel_file = opt_model(
            model_file=model_file,
            param_file=param_file,
            optimize_out_type='protobuf')

        pred = LatencyPredictor()
287 288
        paddle.enable_static()
        with open(pbmodel_file, "rb") as f:
W
whs 已提交
289 290
            _program = paddle.static.Program.parse_from_string(f.read())
            graph = paddleslim.core.GraphWrapper(_program)
291 292 293
            graph_keys = pred._get_key_info_from_graph(graph=graph)
            assert len(graph_keys) > 0

Z
zhouzj 已提交
294 295 296 297 298 299
        self._infer_shape(
            model_dir='test_mobilenetv2',
            model_filename='inference.pdmodel',
            params_filename='inference.pdiparams',
            input_shapes=[1, 3, 250, 250],
            save_path='test_mobilenetv2_250')
300

Z
zhouzj 已提交
301 302
        model_file = 'test_mobilenetv2_250/infered_shape.pdmodel'
        param_file = 'test_mobilenetv2_250/infered_shape.pdiparams'
303 304
        latency = predictor.predict(
            model_file=model_file, param_file=param_file, data_type='fp32')
305 306
        assert latency > 0

Z
zhouzj 已提交
307 308 309 310 311 312
        self._infer_shape(
            model_dir='test_mobilenetv2_qat',
            model_filename='inference.pdmodel',
            params_filename='inference.pdiparams',
            input_shapes=[1, 3, 250, 250],
            save_path='test_mobilenetv2_qat_250')
313

Z
zhouzj 已提交
314 315 316 317 318 319 320 321 322
        model_file = 'test_mobilenetv2_qat_250/infered_shape.pdmodel'
        param_file = 'test_mobilenetv2_qat_250/infered_shape.pdiparams'
        latency = predictor.predict(
            model_file=model_file, param_file=param_file, data_type='int8')
        assert latency > 0


class TestCase3(unittest.TestCase):
    def test_case3(self):
323
        paddle.disable_static()
Z
zhouzj 已提交
324
        model = ModelCase1()
Z
zhouzj 已提交
325
        model_file, param_file = save_cls_model(
326
            model,
Z
zhouzj 已提交
327
            input_shape=[1, 116, 28, 28],
328 329
            save_dir="./inference_model",
            data_type='fp32')
Z
zhouzj 已提交
330
        predictor = TableLatencyPredictor(table_file='SD710')
331 332
        latency = predictor.predict(
            model_file=model_file, param_file=param_file, data_type='fp32')
333 334 335
        assert latency > 0


Z
zhouzj 已提交
336 337
class TestCase4(unittest.TestCase):
    def test_case4(self):
338 339
        paddle.disable_static()
        model = ModelCase2()
340 341
        predictor = TableLatencyPredictor(table_file='SD710')
        model_file, param_file = save_det_model(
342 343
            model,
            input_shape=[1, 3, 224, 224],
344 345 346 347
            save_dir="./inference_model",
            data_type='fp32')
        latency = predictor.predict(
            model_file=model_file, param_file=param_file, data_type='fp32')
348 349 350
        assert latency > 0


Z
zhouzj 已提交
351 352
class TestCase5(unittest.TestCase):
    def test_case5(self):
353 354
        paddle.disable_static()
        model = ModelCase3()
355 356
        predictor = TableLatencyPredictor(table_file='SD710')
        model_file, param_file = save_det_model(
357 358
            model,
            input_shape=[1, 3, 224, 224],
359
            save_dir="./inference_model",
360
            data_type='fp32',
361 362 363
            det_multi_input=True)
        latency = predictor.predict(
            model_file=model_file, param_file=param_file, data_type='fp32')
364 365 366
        assert latency > 0


Z
zhouzj 已提交
367 368
class TestCase6(unittest.TestCase):
    def test_case6(self):
369 370
        paddle.disable_static()
        model = ModelCase4()
371 372
        predictor = LatencyPredictor()
        model_file, param_file = save_cls_model(
373 374
            model,
            input_shape=[1, 3, 16, 16],
375 376 377 378 379 380 381
            save_dir="./inference_model",
            data_type='int8')
        pbmodel_file = opt_model(
            model_file=model_file,
            param_file=param_file,
            optimize_out_type='protobuf')

382 383
        paddle.enable_static()
        with open(pbmodel_file, "rb") as f:
W
whs 已提交
384 385
            _program = paddle.static.Program.parse_from_string(f.read())
            graph = paddleslim.core.GraphWrapper(_program)
386 387 388 389
            graph_keys = predictor._get_key_info_from_graph(graph=graph)
            assert len(graph_keys) > 0


Z
zhouzj 已提交
390 391
class TestCase7(unittest.TestCase):
    def test_case7(self):
392 393
        paddle.disable_static()
        model = ModelCase5()
394 395
        predictor = LatencyPredictor()
        model_file, param_file = save_det_model(
396 397
            model,
            input_shape=[1, 255, 13, 13],
398 399 400 401 402 403 404
            save_dir="./inference_model",
            data_type='fp32')
        pbmodel_file = opt_model(
            model_file=model_file,
            param_file=param_file,
            optimize_out_type='protobuf')

405 406
        paddle.enable_static()
        with open(pbmodel_file, "rb") as f:
W
whs 已提交
407 408
            _program = paddle.static.Program.parse_from_string(f.read())
            graph = paddleslim.core.GraphWrapper(_program)
409 410 411 412
            graph_keys = predictor._get_key_info_from_graph(graph=graph)
            assert len(graph_keys) > 0


Z
zhouzj 已提交
413 414
class TestCase8(unittest.TestCase):
    def test_case8(self):
415 416
        paddle.disable_static()
        predictor = TableLatencyPredictor(table_file='SD710')
Z
zhouzj 已提交
417
        model = ModelCase6()
418 419 420 421 422 423 424 425 426
        model_file, param_file = save_cls_model(
            model,
            input_shape=[1, 3, 16, 16],
            save_dir="./inference_model",
            data_type='fp32')
        latency = predictor.predict(
            model_file=model_file, param_file=param_file, data_type='fp32')
        assert latency > 0

Z
zhouzj 已提交
427 428
        paddle.disable_static()
        model2 = ModelCase7()
429
        model_file, param_file = save_det_model(
Z
zhouzj 已提交
430
            model2,
431 432 433 434 435 436 437 438
            input_shape=[1, 255, 14, 14],
            save_dir="./inference_model",
            data_type='fp32')
        latency = predictor.predict(
            model_file=model_file, param_file=param_file, data_type='fp32')
        assert latency > 0


439 440
if __name__ == '__main__':
    unittest.main()