“8d87b3bcc7015569887ab40276c6005d9bef88a8”上不存在“paddle/phi/kernels/primitive/compute_primitives.h”
test_inference_model_io.py 17.9 KB
Newer Older
1
#   Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
D
dzhwinter 已提交
2
#
D
dzhwinter 已提交
3 4 5
# 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
D
dzhwinter 已提交
6
#
D
dzhwinter 已提交
7
#     http://www.apache.org/licenses/LICENSE-2.0
D
dzhwinter 已提交
8
#
D
dzhwinter 已提交
9 10 11 12 13 14
# 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
import importlib
16
import os
17
import tempfile
18
import unittest
19
import warnings
20

21 22
import numpy as np

23
import paddle
24 25
import paddle.fluid as fluid
import paddle.fluid.core as core
26 27 28
import paddle.fluid.executor as executor
import paddle.fluid.layers as layers
import paddle.fluid.optimizer as optimizer
29
from paddle.distributed.io import load_inference_model_distributed
T
tangwei12 已提交
30
from paddle.fluid.compiler import CompiledProgram
31
from paddle.fluid.framework import Program, program_guard
32 33
from paddle.fluid.io import (
    load_inference_model,
34
    save_inference_model,
35 36
    save_persistables,
)
37

38
paddle.enable_static()
39 40


41
class InferModel:
42 43 44 45 46
    def __init__(self, list):
        self.program = list[0]
        self.feed_var_names = list[1]
        self.fetch_vars = list[2]

47

48
class TestBook(unittest.TestCase):
49
    def test_fit_line_inference_model(self):
50 51 52
        root_path = tempfile.TemporaryDirectory()
        MODEL_DIR = os.path.join(root_path.name, "inference_model")
        UNI_MODEL_DIR = os.path.join(root_path.name, "inference_model1")
53 54 55

        init_program = Program()
        program = Program()
56 57 58 59 60 61 62

        with program_guard(program, init_program):
            x = layers.data(name='x', shape=[2], dtype='float32')
            y = layers.data(name='y', shape=[1], dtype='float32')

            y_predict = layers.fc(input=x, size=1, act=None)

63 64 65
            cost = paddle.nn.functional.square_error_cost(
                input=y_predict, label=y
            )
66
            avg_cost = paddle.mean(cost)
67 68 69

            sgd_optimizer = optimizer.SGDOptimizer(learning_rate=0.001)
            sgd_optimizer.minimize(avg_cost, init_program)
70 71 72 73 74 75

        place = core.CPUPlace()
        exe = executor.Executor(place)

        exe.run(init_program, feed={}, fetch_list=[])

76
        for i in range(100):
77 78 79
            tensor_x = np.array([[1, 1], [1, 2], [3, 4], [5, 2]]).astype(
                "float32"
            )
D
dzhwinter 已提交
80
            tensor_y = np.array([[-2], [-3], [-7], [-7]]).astype("float32")
81

82 83 84 85 86
            exe.run(
                program,
                feed={'x': tensor_x, 'y': tensor_y},
                fetch_list=[avg_cost],
            )
87

88
        # Separated model and unified model
89
        save_inference_model(MODEL_DIR, ["x", "y"], [avg_cost], exe, program)
90 91 92 93 94 95 96 97 98
        save_inference_model(
            UNI_MODEL_DIR,
            ["x", "y"],
            [avg_cost],
            exe,
            program,
            'model',
            'params',
        )
99
        main_program = program.clone()._prune_with_input(
100 101
            feeded_var_names=["x", "y"], targets=[avg_cost]
        )
102 103
        params_str = save_persistables(exe, None, main_program, None)

104 105 106
        expected = exe.run(
            program, feed={'x': tensor_x, 'y': tensor_y}, fetch_list=[avg_cost]
        )[0]
107

108
        importlib.reload(executor)  # reload to build a new scope
109

110
        model_0 = InferModel(load_inference_model(MODEL_DIR, exe))
111 112
        with open(os.path.join(UNI_MODEL_DIR, 'model'), "rb") as f:
            model_str = f.read()
113
        model_1 = InferModel(
114 115
            load_inference_model(None, exe, model_str, params_str)
        )
116 117 118 119
        model_2 = InferModel(load_inference_model_distributed(MODEL_DIR, exe))
        model_3 = InferModel(
            load_inference_model_distributed(None, exe, model_str, params_str)
        )
120

121
        for model in [model_0, model_1, model_2, model_3]:
122 123 124 125 126 127 128 129
            outs = exe.run(
                model.program,
                feed={
                    model.feed_var_names[0]: tensor_x,
                    model.feed_var_names[1]: tensor_y,
                },
                fetch_list=model.fetch_vars,
            )
130 131 132 133 134 135 136
            actual = outs[0]

            self.assertEqual(model.feed_var_names, ["x", "y"])
            self.assertEqual(len(model.fetch_vars), 1)
            print("fetch %s" % str(model.fetch_vars[0]))
            self.assertEqual(expected, actual)

137 138
        root_path.cleanup()

139 140 141 142 143 144 145 146
        self.assertRaises(
            ValueError,
            fluid.io.load_inference_model,
            None,
            exe,
            model_str,
            None,
        )
147 148 149 150 151 152 153 154
        self.assertRaises(
            ValueError,
            load_inference_model_distributed,
            None,
            exe,
            model_str,
            None,
        )
155 156


D
dzhwinter 已提交
157 158
class TestSaveInferenceModel(unittest.TestCase):
    def test_save_inference_model(self):
159 160
        root_path = tempfile.TemporaryDirectory()
        MODEL_DIR = os.path.join(root_path.name, "inference_model2")
D
dzhwinter 已提交
161 162 163 164 165 166 167 168 169 170
        init_program = Program()
        program = Program()

        # fake program without feed/fetch
        with program_guard(program, init_program):
            x = layers.data(name='x', shape=[2], dtype='float32')
            y = layers.data(name='y', shape=[1], dtype='float32')

            y_predict = layers.fc(input=x, size=1, act=None)

171 172 173
            cost = paddle.nn.functional.square_error_cost(
                input=y_predict, label=y
            )
174
            avg_cost = paddle.mean(cost)
D
dzhwinter 已提交
175 176 177 178 179

        place = core.CPUPlace()
        exe = executor.Executor(place)
        exe.run(init_program, feed={}, fetch_list=[])

D
dzhwinter 已提交
180
        save_inference_model(MODEL_DIR, ["x", "y"], [avg_cost], exe, program)
181
        root_path.cleanup()
D
dzhwinter 已提交
182

183
    def test_save_inference_model_with_auc(self):
184 185
        root_path = tempfile.TemporaryDirectory()
        MODEL_DIR = os.path.join(root_path.name, "inference_model4")
186 187 188 189 190 191
        init_program = Program()
        program = Program()

        # fake program without feed/fetch
        with program_guard(program, init_program):
            x = layers.data(name='x', shape=[2], dtype='float32')
192
            y = layers.data(name='y', shape=[1], dtype='int32')
193
            predict = fluid.layers.fc(input=x, size=2, act='softmax')
194 195
            acc = paddle.static.accuracy(input=predict, label=y)
            auc_var, batch_auc_var, auc_states = paddle.static.auc(
196 197
                input=predict, label=y
            )
198 199 200
            cost = paddle.nn.functional.cross_entropy(
                input=predict, label=y, reduction='none', use_softmax=False
            )
201
            avg_cost = paddle.mean(x=cost)
202 203 204 205 206 207

        place = core.CPUPlace()
        exe = executor.Executor(place)
        exe.run(init_program, feed={}, fetch_list=[])
        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter("always")
208 209 210
            save_inference_model(
                MODEL_DIR, ["x", "y"], [avg_cost], exe, program
            )
211
            root_path.cleanup()
212 213 214 215
            expected_warn = "please ensure that you have set the auc states to zeros before saving inference model"
            self.assertTrue(len(w) > 0)
            self.assertTrue(expected_warn == str(w[0].message))

D
dzhwinter 已提交
216

T
tangwei12 已提交
217 218
class TestInstance(unittest.TestCase):
    def test_save_inference_model(self):
219 220
        root_path = tempfile.TemporaryDirectory()
        MODEL_DIR = os.path.join(root_path.name, "inference_model3")
T
tangwei12 已提交
221 222 223 224 225 226 227 228 229 230
        init_program = Program()
        program = Program()

        # fake program without feed/fetch
        with program_guard(program, init_program):
            x = layers.data(name='x', shape=[2], dtype='float32')
            y = layers.data(name='y', shape=[1], dtype='float32')

            y_predict = layers.fc(input=x, size=1, act=None)

231 232 233
            cost = paddle.nn.functional.square_error_cost(
                input=y_predict, label=y
            )
234
            avg_cost = paddle.mean(cost)
T
tangwei12 已提交
235 236 237 238 239 240 241 242

        place = core.CPUPlace()
        exe = executor.Executor(place)
        exe.run(init_program, feed={}, fetch_list=[])

        # will print warning message

        cp_prog = CompiledProgram(program).with_data_parallel(
243 244
            loss_name=avg_cost.name
        )
T
tangwei12 已提交
245

C
chengduo 已提交
246
        save_inference_model(MODEL_DIR, ["x", "y"], [avg_cost], exe, cp_prog)
247 248 249 250 251
        self.assertRaises(
            TypeError,
            save_inference_model,
            [MODEL_DIR, ["x", "y"], [avg_cost], [], cp_prog],
        )
252
        root_path.cleanup()
T
tangwei12 已提交
253 254


255 256
class TestSaveInferenceModelNew(unittest.TestCase):
    def test_save_and_load_inference_model(self):
257 258
        root_path = tempfile.TemporaryDirectory()
        MODEL_DIR = os.path.join(root_path.name, "inference_model5")
259 260 261 262 263 264 265 266 267 268
        init_program = fluid.default_startup_program()
        program = fluid.default_main_program()

        # fake program without feed/fetch
        with program_guard(program, init_program):
            x = layers.data(name='x', shape=[2], dtype='float32')
            y = layers.data(name='y', shape=[1], dtype='float32')

            y_predict = layers.fc(input=x, size=1, act=None)

269 270 271
            cost = paddle.nn.functional.square_error_cost(
                input=y_predict, label=y
            )
272
            avg_cost = paddle.mean(cost)
273 274 275 276 277 278 279 280 281 282

            sgd_optimizer = optimizer.SGDOptimizer(learning_rate=0.001)
            sgd_optimizer.minimize(avg_cost, init_program)

        place = core.CPUPlace()
        exe = executor.Executor(place)
        exe.run(init_program, feed={}, fetch_list=[])

        tensor_x = np.array([[1, 1], [1, 2], [5, 2]]).astype("float32")
        tensor_y = np.array([[-2], [-3], [-7]]).astype("float32")
283
        for i in range(3):
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
            exe.run(
                program,
                feed={'x': tensor_x, 'y': tensor_y},
                fetch_list=[avg_cost],
            )

        self.assertRaises(
            ValueError,
            paddle.static.save_inference_model,
            None,
            ['x', 'y'],
            [avg_cost],
            exe,
        )
        self.assertRaises(
            ValueError,
            paddle.static.save_inference_model,
            MODEL_DIR + "/",
            [x, y],
            [avg_cost],
            exe,
        )
        self.assertRaises(
            ValueError,
            paddle.static.save_inference_model,
            MODEL_DIR,
            ['x', 'y'],
            [avg_cost],
            exe,
        )
        self.assertRaises(
            ValueError,
            paddle.static.save_inference_model,
            MODEL_DIR,
            'x',
            [avg_cost],
            exe,
        )
        self.assertRaises(
            ValueError,
            paddle.static.save_inference_model,
            MODEL_DIR,
            [x, y],
            ['avg_cost'],
            exe,
        )
        self.assertRaises(
            ValueError,
            paddle.static.save_inference_model,
            MODEL_DIR,
            [x, y],
            'avg_cost',
            exe,
        )
338 339 340

        model_path = MODEL_DIR + "_isdir.pdmodel"
        os.makedirs(model_path)
341 342 343 344 345 346 347 348
        self.assertRaises(
            ValueError,
            paddle.static.save_inference_model,
            MODEL_DIR + "_isdir",
            [x, y],
            [avg_cost],
            exe,
        )
349 350 351 352
        os.rmdir(model_path)

        params_path = MODEL_DIR + "_isdir.pdmodel"
        os.makedirs(params_path)
353 354 355 356 357 358 359 360
        self.assertRaises(
            ValueError,
            paddle.static.save_inference_model,
            MODEL_DIR + "_isdir",
            [x, y],
            [avg_cost],
            exe,
        )
361 362
        os.rmdir(params_path)

363 364 365
        paddle.static.io.save_inference_model(
            MODEL_DIR, [x, y], [avg_cost], exe
        )
366 367 368 369

        self.assertTrue(os.path.exists(MODEL_DIR + ".pdmodel"))
        self.assertTrue(os.path.exists(MODEL_DIR + ".pdiparams"))

370 371 372
        expected = exe.run(
            program, feed={'x': tensor_x, 'y': tensor_y}, fetch_list=[avg_cost]
        )[0]
373

374
        importlib.reload(executor)  # reload to build a new scope
375

376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
        self.assertRaises(
            ValueError, paddle.static.load_inference_model, None, exe
        )
        self.assertRaises(
            ValueError, paddle.static.load_inference_model, MODEL_DIR + "/", exe
        )
        self.assertRaises(
            ValueError, paddle.static.load_inference_model, [MODEL_DIR], exe
        )
        self.assertRaises(
            ValueError,
            paddle.static.load_inference_model,
            MODEL_DIR,
            exe,
            pserver_endpoints=None,
        )
        self.assertRaises(
            ValueError,
            paddle.static.load_inference_model,
            MODEL_DIR,
            exe,
            unsupported_param=None,
        )
        self.assertRaises(
            (TypeError, ValueError),
            paddle.static.load_inference_model,
            None,
            exe,
            model_filename="illegal",
            params_filename="illegal",
        )

        model = InferModel(
            paddle.static.io.load_inference_model(MODEL_DIR, exe)
        )
411
        root_path.cleanup()
412

413 414 415 416 417 418 419 420
        outs = exe.run(
            model.program,
            feed={
                model.feed_var_names[0]: tensor_x,
                model.feed_var_names[1]: tensor_y,
            },
            fetch_list=model.fetch_vars,
        )
421 422 423 424 425
        actual = outs[0]

        self.assertEqual(model.feed_var_names, ["x", "y"])
        self.assertEqual(len(model.fetch_vars), 1)
        self.assertEqual(expected, actual)
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447
        # test save_to_file content type should be bytes
        self.assertRaises(ValueError, paddle.static.io.save_to_file, '', 123)
        # test _get_valid_program
        self.assertRaises(TypeError, paddle.static.io._get_valid_program, 0)
        p = Program()
        cp = CompiledProgram(p)
        paddle.static.io._get_valid_program(cp)
        self.assertTrue(paddle.static.io._get_valid_program(cp) is p)
        cp._program = None
        self.assertRaises(TypeError, paddle.static.io._get_valid_program, cp)

    def test_serialize_program_and_persistables(self):
        init_program = fluid.default_startup_program()
        program = fluid.default_main_program()

        # fake program without feed/fetch
        with program_guard(program, init_program):
            x = layers.data(name='x', shape=[2], dtype='float32')
            y = layers.data(name='y', shape=[1], dtype='float32')

            y_predict = layers.fc(input=x, size=1, act=None)

448 449 450
            cost = paddle.nn.functional.square_error_cost(
                input=y_predict, label=y
            )
451
            avg_cost = paddle.mean(cost)
452 453 454 455 456 457 458 459 460 461

            sgd_optimizer = optimizer.SGDOptimizer(learning_rate=0.001)
            sgd_optimizer.minimize(avg_cost, init_program)

        place = core.CPUPlace()
        exe = executor.Executor(place)
        exe.run(init_program, feed={}, fetch_list=[])

        tensor_x = np.array([[1, 1], [1, 2], [5, 2]]).astype("float32")
        tensor_y = np.array([[-2], [-3], [-7]]).astype("float32")
462
        for i in range(3):
463 464 465 466 467
            exe.run(
                program,
                feed={'x': tensor_x, 'y': tensor_y},
                fetch_list=[avg_cost],
            )
468

469 470 471 472 473 474 475 476
        # test if return type of serialize_program is bytes
        res1 = paddle.static.io.serialize_program([x, y], [avg_cost])
        self.assertTrue(isinstance(res1, bytes))
        # test if return type of serialize_persistables is bytes
        res2 = paddle.static.io.serialize_persistables([x, y], [avg_cost], exe)
        self.assertTrue(isinstance(res2, bytes))
        # test if variables in program is empty
        res = paddle.static.io._serialize_persistables(Program(), None)
477
        self.assertIsNone(res)
478 479 480 481 482 483 484
        self.assertRaises(
            TypeError,
            paddle.static.io.deserialize_persistables,
            None,
            None,
            None,
        )
485

486 487 488 489 490 491 492 493 494 495 496
    def test_normalize_program(self):
        init_program = fluid.default_startup_program()
        program = fluid.default_main_program()

        # fake program without feed/fetch
        with program_guard(program, init_program):
            x = layers.data(name='x', shape=[2], dtype='float32')
            y = layers.data(name='y', shape=[1], dtype='float32')

            y_predict = layers.fc(input=x, size=1, act=None)

497 498 499
            cost = paddle.nn.functional.square_error_cost(
                input=y_predict, label=y
            )
500
            avg_cost = paddle.mean(cost)
501 502 503 504 505 506 507 508 509 510

            sgd_optimizer = optimizer.SGDOptimizer(learning_rate=0.001)
            sgd_optimizer.minimize(avg_cost, init_program)

        place = core.CPUPlace()
        exe = executor.Executor(place)
        exe.run(init_program, feed={}, fetch_list=[])

        tensor_x = np.array([[1, 1], [1, 2], [5, 2]]).astype("float32")
        tensor_y = np.array([[-2], [-3], [-7]]).astype("float32")
511
        for i in range(3):
512 513 514 515 516
            exe.run(
                program,
                feed={'x': tensor_x, 'y': tensor_y},
                fetch_list=[avg_cost],
            )
517 518 519 520 521

        # test if return type of serialize_program is bytes
        res = paddle.static.normalize_program(program, [x, y], [avg_cost])
        self.assertTrue(isinstance(res, Program))
        # test program type
522 523 524
        self.assertRaises(
            TypeError, paddle.static.normalize_program, None, [x, y], [avg_cost]
        )
525
        # test feed_vars type
526 527 528
        self.assertRaises(
            TypeError, paddle.static.normalize_program, program, 'x', [avg_cost]
        )
529
        # test fetch_vars type
530 531 532 533 534 535 536
        self.assertRaises(
            TypeError,
            paddle.static.normalize_program,
            program,
            [x, y],
            'avg_cost',
        )
537

538

539 540 541 542
class TestLoadInferenceModelError(unittest.TestCase):
    def test_load_model_not_exist(self):
        place = core.CPUPlace()
        exe = executor.Executor(place)
543 544 545
        self.assertRaises(
            ValueError, load_inference_model, './test_not_exist_dir', exe
        )
546 547 548 549 550 551
        self.assertRaises(
            ValueError,
            load_inference_model_distributed,
            './test_not_exist_dir',
            exe,
        )
552 553


554 555
if __name__ == '__main__':
    unittest.main()