test_latency_predictor.py 15.3 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 151 152 153 154 155 156 157
        x = paddle.slice(x, axes=[0], starts=[0], ends=[1])
        x = paddle.exp(x)
        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)
158 159 160 161
        outshape = out1.shape
        max_idx = paddle.argmax(
            out1.reshape((outshape[0], outshape[1], outshape[2] * outshape[3])),
            axis=-1)
Z
zhouzj 已提交
162 163
        out2 = out2.reshape((outshape[0], outshape[1],
                             outshape[2] * outshape[3]))
164 165
        res, _ = self.lstm(out2)
        return res, max_idx
166 167 168 169 170


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

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


Z
zhouzj 已提交
191 192 193 194 195 196 197 198 199 200 201
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')

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

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


class TestCase2(unittest.TestCase):
Z
zhouzj 已提交
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
    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)
Z
zhouzj 已提交
239 240 241
        [inference_program, feed_target_names,
         fetch_targets] = (paddle.static.load_inference_model(
             path_prefix=model_path_prefix, executor=exe))
Z
zhouzj 已提交
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

        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}")

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

279 280 281 282 283 284
        pbmodel_file = opt_model(
            model_file=model_file,
            param_file=param_file,
            optimize_out_type='protobuf')

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

Z
zhouzj 已提交
292 293 294 295 296 297
        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')
298

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

Z
zhouzj 已提交
305 306 307 308 309 310
        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')
311

Z
zhouzj 已提交
312 313 314 315 316 317 318 319 320
        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):
321
        paddle.disable_static()
Z
zhouzj 已提交
322
        model = ModelCase1()
Z
zhouzj 已提交
323
        model_file, param_file = save_cls_model(
324
            model,
Z
zhouzj 已提交
325
            input_shape=[1, 116, 28, 28],
326 327
            save_dir="./inference_model",
            data_type='fp32')
Z
zhouzj 已提交
328
        predictor = TableLatencyPredictor(table_file='SD710')
329 330
        latency = predictor.predict(
            model_file=model_file, param_file=param_file, data_type='fp32')
331 332 333
        assert latency > 0


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


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


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

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


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

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


Z
zhouzj 已提交
411 412
class TestCase8(unittest.TestCase):
    def test_case8(self):
413 414
        paddle.disable_static()
        predictor = TableLatencyPredictor(table_file='SD710')
Z
zhouzj 已提交
415
        model = ModelCase6()
416 417 418 419 420 421 422 423 424
        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 已提交
425 426
        paddle.disable_static()
        model2 = ModelCase7()
427
        model_file, param_file = save_det_model(
Z
zhouzj 已提交
428
            model2,
429 430 431 432 433 434 435 436
            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


437 438
if __name__ == '__main__':
    unittest.main()