From 45e7c75d61ced68d7a5b51f044caf0dd7de90fb4 Mon Sep 17 00:00:00 2001 From: Hui Zhang Date: Mon, 25 Jul 2022 07:25:38 +0000 Subject: [PATCH 1/6] jit.save support peropty serilization --- python/paddle/fluid/dygraph/io.py | 1 + python/paddle/fluid/dygraph/jit.py | 34 +++++++++++++++++-- .../dygraph_to_static/test_property_save.py | 5 ++- .../tests/unittests/test_jit_save_load.py | 28 +++++++++++---- 4 files changed, 59 insertions(+), 9 deletions(-) diff --git a/python/paddle/fluid/dygraph/io.py b/python/paddle/fluid/dygraph/io.py index a778cc3a1c688..7f91a15ff0149 100644 --- a/python/paddle/fluid/dygraph/io.py +++ b/python/paddle/fluid/dygraph/io.py @@ -37,6 +37,7 @@ INFER_MODEL_SUFFIX = ".pdmodel" INFER_PARAMS_SUFFIX = ".pdiparams" INFER_PARAMS_INFO_SUFFIX = ".pdiparams.info" +INFER_PROPERTY_SUFFIX = '.meta' LOADED_VAR_SUFFIX = "load" PARAMETER_NAME_PREFIX = "param" diff --git a/python/paddle/fluid/dygraph/jit.py b/python/paddle/fluid/dygraph/jit.py index a55bcb9aaaba6..5ae87b029af1d 100644 --- a/python/paddle/fluid/dygraph/jit.py +++ b/python/paddle/fluid/dygraph/jit.py @@ -34,7 +34,7 @@ from paddle.fluid.dygraph.dygraph_to_static.convert_call_func import ConversionOptions, CONVERSION_OPTIONS from paddle.fluid.dygraph.dygraph_to_static.logging_utils import set_code_level, set_verbosity from paddle.fluid.dygraph.dygraph_to_static.program_translator import ProgramTranslator, StaticFunction, unwrap_decorators -from paddle.fluid.dygraph.io import TranslatedLayer, INFER_MODEL_SUFFIX, INFER_PARAMS_SUFFIX, INFER_PARAMS_INFO_SUFFIX +from paddle.fluid.dygraph.io import TranslatedLayer, INFER_MODEL_SUFFIX, INFER_PARAMS_SUFFIX, INFER_PARAMS_INFO_SUFFIX, INFER_PROPERTY_SUFFIX from paddle.fluid.dygraph.layers import Layer from paddle.fluid.executor import Executor, scope_guard from paddle.fluid.framework import Block, ParamBase, Program, Variable, Parameter, EagerParamBase @@ -1034,7 +1034,37 @@ def fun(inputs): filter(paddle.fluid.io.is_persistable, all_vars)), filename=params_filename) - # TODO: save property + # save property + property_filename = file_prefix + INFER_PROPERTY_SUFFIX + + def set_property(meta, key, val): + if isinstance(val, float): + meta.set_float(key, val) + elif isinstance(val, int): + meta.set_int(key, val) + elif isinstance(val, str): + meta.set_string(key, val) + elif isinstance(val, paddle.Tensor): + meta.set_tensor(key, val) + elif isinstance(val, (tuple, list)): + if isinstance(val[0], float): + meta.set_floats(key, val) + elif isinstance(val[0], int): + meta.set_ints(key, val) + elif isinstance(val[0], str): + meta.set_strings(key, val) + elif isinstance(val[0], paddle.Tensor): + meta.set_tensors(key, val) + else: + raise ValueError(f"Note support val type: {type(val)}") + return + + with open(property_filename, 'wb') as f: + meta = paddle.framework.core.Property() + for item in property_vals: + val, key = item[0], item[1] + set_property(meta, key, val) + f.write(meta.serialize_to_string()) # NOTE(chenweihang): [ Save extra variable info ] # save_inference_model will lose some important variable information, including: diff --git a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_property_save.py b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_property_save.py index 59c67bfcb49a6..df69ae3dbd279 100644 --- a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_property_save.py +++ b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_property_save.py @@ -49,7 +49,10 @@ def test_set_float_wo_name(self): """ a = paddle.framework.core.Property() a.set_float(10.0) - self.assertEqual(a.get_float(0), 10.0) + self.assertAlmostEqual(a.get_float(0), 10.0) + + a.set_float("ftest", 1.4) + self.assertAlmostEqual(a.get_float('ftest'), 1.4) def test_set(self): """test propety set. diff --git a/python/paddle/fluid/tests/unittests/test_jit_save_load.py b/python/paddle/fluid/tests/unittests/test_jit_save_load.py index eab86141ba6b1..262cde4aa241e 100644 --- a/python/paddle/fluid/tests/unittests/test_jit_save_load.py +++ b/python/paddle/fluid/tests/unittests/test_jit_save_load.py @@ -1156,7 +1156,7 @@ def forward(self, x): class Net(paddle.nn.Layer): def __init__(self): - super(Net, self).__init__() + super().__init__() self.fc1 = paddle.nn.Linear(4, 4) self.fc2 = paddle.nn.Linear(4, 4) self.bias = 0.4 @@ -1185,13 +1185,28 @@ def infer(self, input): def fbias(self): return self.bias + 1 - # For extra Tensor @paddle.jit.to_static(property=True) - def fflag(self): - return self.flag + def down_sampling(self): + return 4 + @paddle.jit.to_static(property=True) + def fstr(self): + return "save str property" + + @paddle.jit.to_static(property=True) + def ints(self): + return [10, 20] + + @paddle.jit.to_static(property=True) + def floats(self): + return [1.1, 2.2] -class TestJitSaveCombine(unittest.TestCase): + @paddle.jit.to_static(property=True) + def strs(self): + return ["hello", "world"] + + +class TestJitSaveCombineProperty(unittest.TestCase): def setUp(self): # enable dygraph mode @@ -1201,13 +1216,14 @@ def setUp(self): def tearDown(self): self.temp_dir.cleanup() - def test_save_load_finetune_load(self): + def test_jit_save_combine_property(self): model_path = os.path.join(self.temp_dir.name, "test_jit_save_combine/model") # Use new namespace with unique_name.guard(): net = Net() + #save paddle.jit.save(net, model_path, combine_params=True) From 301f6aa60223b3fb971d10120e909666ebec71ec Mon Sep 17 00:00:00 2001 From: Hui Zhang Date: Tue, 26 Jul 2022 02:46:16 +0000 Subject: [PATCH 2/6] extract set property function --- python/paddle/fluid/dygraph/jit.py | 68 +++++++++++++++++------------- 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/python/paddle/fluid/dygraph/jit.py b/python/paddle/fluid/dygraph/jit.py index 5ae87b029af1d..b1ecffb98c581 100644 --- a/python/paddle/fluid/dygraph/jit.py +++ b/python/paddle/fluid/dygraph/jit.py @@ -644,6 +644,44 @@ def wrapper(layer, path, input_spec=None, **configs): return wrapper +def _save_property(filename: Text, property_vals: List[Tuple(Any, Text)]): + """class property serialization. + + Args: + filename (Text): *.meta + property_vals (List[Tuple): class property. + """ + + def set_property(meta, key, val): + if isinstance(val, float): + meta.set_float(key, val) + elif isinstance(val, int): + meta.set_int(key, val) + elif isinstance(val, str): + meta.set_string(key, val) + elif isinstance(val, paddle.Tensor): + meta.set_tensor(key, val) + elif isinstance(val, (tuple, list)): + if isinstance(val[0], float): + meta.set_floats(key, val) + elif isinstance(val[0], int): + meta.set_ints(key, val) + elif isinstance(val[0], str): + meta.set_strings(key, val) + elif isinstance(val[0], paddle.Tensor): + meta.set_tensors(key, val) + else: + raise ValueError(f"Note support val type: {type(val)}") + return + + with open(filename, 'wb') as f: + meta = paddle.framework.core.Property() + for item in property_vals: + val, key = item[0], item[1] + set_property(meta, key, val) + f.write(meta.serialize_to_string()) + + @_run_save_pre_hooks @switch_to_static_graph def save(layer, path, input_spec=None, **configs): @@ -1036,35 +1074,7 @@ def fun(inputs): filename=params_filename) # save property property_filename = file_prefix + INFER_PROPERTY_SUFFIX - - def set_property(meta, key, val): - if isinstance(val, float): - meta.set_float(key, val) - elif isinstance(val, int): - meta.set_int(key, val) - elif isinstance(val, str): - meta.set_string(key, val) - elif isinstance(val, paddle.Tensor): - meta.set_tensor(key, val) - elif isinstance(val, (tuple, list)): - if isinstance(val[0], float): - meta.set_floats(key, val) - elif isinstance(val[0], int): - meta.set_ints(key, val) - elif isinstance(val[0], str): - meta.set_strings(key, val) - elif isinstance(val[0], paddle.Tensor): - meta.set_tensors(key, val) - else: - raise ValueError(f"Note support val type: {type(val)}") - return - - with open(property_filename, 'wb') as f: - meta = paddle.framework.core.Property() - for item in property_vals: - val, key = item[0], item[1] - set_property(meta, key, val) - f.write(meta.serialize_to_string()) + _save_property(property_filename, property_vals) # NOTE(chenweihang): [ Save extra variable info ] # save_inference_model will lose some important variable information, including: From e3237735d9ef1034422b175fbc7fc07e15fe4c01 Mon Sep 17 00:00:00 2001 From: Hui Zhang Date: Tue, 26 Jul 2022 02:47:58 +0000 Subject: [PATCH 3/6] fix property test file name --- .../{test_property_save.py => test_jit_property_save.py} | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) rename python/paddle/fluid/tests/unittests/dygraph_to_static/{test_property_save.py => test_jit_property_save.py} (93%) diff --git a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_property_save.py b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_jit_property_save.py similarity index 93% rename from python/paddle/fluid/tests/unittests/dygraph_to_static/test_property_save.py rename to python/paddle/fluid/tests/unittests/dygraph_to_static/test_jit_property_save.py index df69ae3dbd279..59c67bfcb49a6 100644 --- a/python/paddle/fluid/tests/unittests/dygraph_to_static/test_property_save.py +++ b/python/paddle/fluid/tests/unittests/dygraph_to_static/test_jit_property_save.py @@ -49,10 +49,7 @@ def test_set_float_wo_name(self): """ a = paddle.framework.core.Property() a.set_float(10.0) - self.assertAlmostEqual(a.get_float(0), 10.0) - - a.set_float("ftest", 1.4) - self.assertAlmostEqual(a.get_float('ftest'), 1.4) + self.assertEqual(a.get_float(0), 10.0) def test_set(self): """test propety set. From a7795e5eae8d8222e428d46ef327d2c9efb44513 Mon Sep 17 00:00:00 2001 From: Hui Zhang Date: Tue, 26 Jul 2022 03:52:39 +0000 Subject: [PATCH 4/6] fix typing error --- python/paddle/fluid/dygraph/jit.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/paddle/fluid/dygraph/jit.py b/python/paddle/fluid/dygraph/jit.py index b1ecffb98c581..f672c370ef72f 100644 --- a/python/paddle/fluid/dygraph/jit.py +++ b/python/paddle/fluid/dygraph/jit.py @@ -22,6 +22,7 @@ from collections import OrderedDict import inspect import threading +from typing import Text, Tuple, Any, List import six import paddle From 71cd8be99ced1866ba576b8835ad6fc511e08d7a Mon Sep 17 00:00:00 2001 From: Hui Zhang Date: Tue, 26 Jul 2022 06:21:17 +0000 Subject: [PATCH 5/6] fix typing error --- python/paddle/fluid/dygraph/jit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/paddle/fluid/dygraph/jit.py b/python/paddle/fluid/dygraph/jit.py index f672c370ef72f..35a23be616a8c 100644 --- a/python/paddle/fluid/dygraph/jit.py +++ b/python/paddle/fluid/dygraph/jit.py @@ -645,7 +645,7 @@ def wrapper(layer, path, input_spec=None, **configs): return wrapper -def _save_property(filename: Text, property_vals: List[Tuple(Any, Text)]): +def _save_property(filename: Text, property_vals: List[Tuple[Any, Text]]): """class property serialization. Args: From e4c443e05a27d14d9daf7afc3d1e79e6f94ef8d2 Mon Sep 17 00:00:00 2001 From: Hui Zhang Date: Tue, 26 Jul 2022 10:57:40 +0000 Subject: [PATCH 6/6] fix test coverage --- paddle/fluid/pybind/protobuf.cc | 9 ----- python/paddle/fluid/dygraph/jit.py | 4 --- .../tests/unittests/test_jit_save_load.py | 33 +++++++++++++++++-- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/paddle/fluid/pybind/protobuf.cc b/paddle/fluid/pybind/protobuf.cc index b30f5f4257d5c..6509ab8e46348 100644 --- a/paddle/fluid/pybind/protobuf.cc +++ b/paddle/fluid/pybind/protobuf.cc @@ -433,15 +433,6 @@ void BindJitProperty(pybind11::module *m) { "set list of string", py::arg("name"), py::arg("val")) - .def("set_tensor", - [](const pd::VarDesc &tensor, const std::string name) { - throw platform::errors::Unimplemented("Not implement set_tensor."); - }) - .def( - "set_tensors", - [](const pybind11::list &tensors, const std::string name) { - throw platform::errors::Unimplemented("Not implement set_tensors."); - }) .def("serialize_to_string", SerializeMessage) .def("parse_from_string", DeserializeMessage); } diff --git a/python/paddle/fluid/dygraph/jit.py b/python/paddle/fluid/dygraph/jit.py index 35a23be616a8c..b18c1c90ca985 100644 --- a/python/paddle/fluid/dygraph/jit.py +++ b/python/paddle/fluid/dygraph/jit.py @@ -660,8 +660,6 @@ def set_property(meta, key, val): meta.set_int(key, val) elif isinstance(val, str): meta.set_string(key, val) - elif isinstance(val, paddle.Tensor): - meta.set_tensor(key, val) elif isinstance(val, (tuple, list)): if isinstance(val[0], float): meta.set_floats(key, val) @@ -669,8 +667,6 @@ def set_property(meta, key, val): meta.set_ints(key, val) elif isinstance(val[0], str): meta.set_strings(key, val) - elif isinstance(val[0], paddle.Tensor): - meta.set_tensors(key, val) else: raise ValueError(f"Note support val type: {type(val)}") return diff --git a/python/paddle/fluid/tests/unittests/test_jit_save_load.py b/python/paddle/fluid/tests/unittests/test_jit_save_load.py index 262cde4aa241e..6aef26ac65ba0 100644 --- a/python/paddle/fluid/tests/unittests/test_jit_save_load.py +++ b/python/paddle/fluid/tests/unittests/test_jit_save_load.py @@ -1,4 +1,5 @@ # Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +# Copyright (c) 2020 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. @@ -1206,6 +1207,27 @@ def strs(self): return ["hello", "world"] +class NetTensor(paddle.nn.Layer): + + def __init__(self): + super().__init__() + self.fc1 = paddle.nn.Linear(4, 4) + self.fc2 = paddle.nn.Linear(4, 4) + self.bias = 0.4 + self.flag = paddle.ones([2], dtype="int32") + + @paddle.jit.to_static(input_spec=[InputSpec([None, 4], dtype='float32')]) + def forward(self, x): + out = self.fc1(x) + out = paddle.nn.functional.relu(out) + out = paddle.mean(out) + return out + + @paddle.jit.to_static(property=True) + def fflag(self): + return True + + class TestJitSaveCombineProperty(unittest.TestCase): def setUp(self): @@ -1219,14 +1241,21 @@ def tearDown(self): def test_jit_save_combine_property(self): model_path = os.path.join(self.temp_dir.name, "test_jit_save_combine/model") - # Use new namespace with unique_name.guard(): net = Net() - #save paddle.jit.save(net, model_path, combine_params=True) + def test_jit_save_tensor_property(self): + model_path = os.path.join(self.temp_dir.name, + "test_jit_save_combine/model") + # Use new namespace + with unique_name.guard(): + net = NetTensor() + + paddle.jit.save(net, model_path, combine_params=True) + class LayerLoadFinetune(paddle.nn.Layer):