From d81192c5cf9538d07d466a6fbf5fc030a0845a07 Mon Sep 17 00:00:00 2001 From: WeiXin Date: Tue, 11 May 2021 02:31:16 +0000 Subject: [PATCH 01/18] paddle.save/load2.1 --- .../api/paddle/fluid/dygraph/jit/save_cn.rst | 30 ++++++- .../api/paddle/fluid/framework/Program_cn.rst | 72 +++++++++++++++ .../paddle/fluid/framework/Variable_cn.rst | 89 +++++++++++++++++++ .../api/paddle/framework/io/load_cn.rst | 46 +++++++++- .../api/paddle/framework/io/save_cn.rst | 41 ++++++++- .../08_model_save_load_cn.rst | 17 ++++ 6 files changed, 287 insertions(+), 8 deletions(-) diff --git a/doc/paddle/api/paddle/fluid/dygraph/jit/save_cn.rst b/doc/paddle/api/paddle/fluid/dygraph/jit/save_cn.rst index 51e8f2e503e..a43efdc2531 100644 --- a/doc/paddle/api/paddle/fluid/dygraph/jit/save_cn.rst +++ b/doc/paddle/api/paddle/fluid/dygraph/jit/save_cn.rst @@ -5,7 +5,7 @@ save .. py:function:: paddle.jit.save(layer, path, input_spec=None, **configs) -将输入的 ``Layer`` 存储为 ``paddle.jit.TranslatedLayer`` 格式的模型,载入后可用于预测推理或者fine-tune训练。 +将输入的 ``Layer`` 或 ``function`` 存储为 ``paddle.jit.TranslatedLayer`` 格式的模型,载入后可用于预测推理或者fine-tune训练。 该接口会将输入 ``Layer`` 转写后的模型结构 ``Program`` 和所有必要的持久参数变量存储至输入路径 ``path`` 。 @@ -16,9 +16,12 @@ save - ``paddle.static.load_inference_model`` - 其他预测库API +.. note:: + 当使用 ``paddle.jit.save`` 保存 ``function`` 时, ``function`` 不能包含参数变量。如果您必须保存参数变量,请用Layer封装function,然后按照处理Layer的方式调用相应的API。 + 参数 ::::::::: - - layer (Layer) - 需要存储的 ``Layer`` 对象。 + - layer (Layer|function) - 需要存储的 ``Layer`` 对象或者 ``function``。 - path (str) - 存储模型的路径前缀。格式为 ``dirname/file_prefix`` 或者 ``file_prefix`` 。 - input_spec (list[InputSpec|Tensor], 可选) - 描述存储模型forward方法的输入,可以通过InputSpec或者示例Tensor进行描述。如果为 ``None`` ,所有原 ``Layer`` forward方法的输入变量将都会被配置为存储模型的输入变量。默认为 ``None``。 - **configs (dict, 可选) - 其他用于兼容的存储配置选项。这些选项将来可能被移除,如果不是必须使用,不推荐使用这些配置选项。默认为 ``None``。目前支持以下配置选项:(1) output_spec (list[Tensor]) - 选择存储模型的输出目标。默认情况下,所有原 ``Layer`` forward方法的返回值均会作为存储模型的输出。如果传入的 ``output_spec`` 列表不是所有的输出变量,存储的模型将会根据 ``output_spec`` 所包含的结果被裁剪。 @@ -32,6 +35,7 @@ save .. code-block:: python + # example 1: save layer import numpy as np import paddle import paddle.nn as nn @@ -98,3 +102,25 @@ save # save path = "example_model/linear" paddle.jit.save(layer, path) + + # example 2: save function + import paddle + from paddle.static import InputSpec + + + def save_function(): + @paddle.jit.to_static + def fun(inputs): + return paddle.tanh(inputs) + + path = 'test_jit_save_load_function_1/func' + inps = paddle.rand([3, 6]) + origin = fun(inps) + + paddle.jit.save(fun, path) + load_func = paddle.jit.load(path) + + load_result = load_func(inps) + print((load_result - origin).abs().max() < 1e-10) + + save_function() diff --git a/doc/paddle/api/paddle/fluid/framework/Program_cn.rst b/doc/paddle/api/paddle/fluid/framework/Program_cn.rst index a74359ae148..4eb4a3401bb 100644 --- a/doc/paddle/api/paddle/fluid/framework/Program_cn.rst +++ b/doc/paddle/api/paddle/fluid/framework/Program_cn.rst @@ -469,3 +469,75 @@ list[ :ref:`api_guide_parameter` ],一个包含当前Program中所有参数的 # Here print(param) will print out all the properties of a parameter, # including name, type and persistable, you can access to specific # property of a parameter, such as param.name, param.type + +.. py:method:: state_dict(mode='all', scope=None) + +获取当前层及其子层的所有参数和可持久性buffers。并将所有参数和buffers存放在dict结构中。 + +参数 +::::::::: + - mode (str, 可选) - 获取何种参数和可持久性buffers。目前支持以下选项: (1) 'opt':获得优化器的参数和可持久性buffers放在dict结构中; (2) 'param':获得组网中的参数和可持久性buffers放在dict结构中,不包含优化器中的参数和可持久性buffers; (3) 'all':获得组网和优化器中的参数和可持久性buffers放在dict结构中;默认值为'all'。 + - scope (Scope, 可选) - 如果scope为``None``,通过 :ref:`api_guide_global_scope` 获取全局/默认作用域实例,并从中获取``state_dict``;否则从指定的``scope``获取``state_dict``。默认值为``None``。 + +返回 +::::::::: +dict, 包含所有参数和可持久行buffers的dict + +代码示例 +::::::::: + +.. code-block:: python + + import paddle + import paddle.static as static + + paddle.enable_static() + + x = static.data(name="x", shape=[10, 10], dtype='float32') + y = static.nn.fc(x, 10) + z = static.nn.fc(y, 10) + + place = paddle.CPUPlace() + exe = static.Executor(place) + exe.run(static.default_startup_program()) + prog = static.default_main_program() + + path = "./temp/model.pdparams" + paddle.save(prog.state_dict(), path) + +.. py:method:: set_state_dict(state_dict, scope=None) + +获取当前层及其子层的所有参数和可持久性buffers。并将所有参数和buffers存放在dict结构中。 + +参数 +::::::::: + - state_dict (dict) - 包含参数和可持久性buffers的字典。键值是参数和可持久性buffers的名字,值为参数和可持久性buffers。 + - scope (Scope, 可选) - 如果scope为``None``,通过 :ref:`api_guide_global_scope` 获取全局/默认作用域实例,并将``state_dict``中参数和可持久性buffers设置到这个作用域中;否则将``state_dict``设置到指定的``scope``中。默认值为``None``。 + +返回 +::::::::: +None + +代码示例 +::::::::: + +.. code-block:: python + + import paddle + import paddle.static as static + + paddle.enable_static() + + x = static.data(name="x", shape=[10, 10], dtype='float32') + y = static.nn.fc(x, 10) + z = static.nn.fc(y, 10) + + place = paddle.CPUPlace() + exe = static.Executor(place) + exe.run(static.default_startup_program()) + prog = static.default_main_program() + + path = "./temp/model.pdparams" + paddle.save(prog.state_dict(), path) + state_dict_load = paddle.load(path) + prog.set_state_dict(state_dict_load) diff --git a/doc/paddle/api/paddle/fluid/framework/Variable_cn.rst b/doc/paddle/api/paddle/fluid/framework/Variable_cn.rst index b3d76960758..ecc1c80d921 100644 --- a/doc/paddle/api/paddle/fluid/framework/Variable_cn.rst +++ b/doc/paddle/api/paddle/fluid/framework/Variable_cn.rst @@ -114,6 +114,95 @@ Variable print("new var's dtype is: {}".format(new_variable.dtype)) +.. py:method:: get_value(scope=None) + +获取 :ref:`api_guide_Variable` 的值。 + +参数 +::::::::: + - scope ( Scope,可选 ) - 从指定的``scope``中获取 :ref:`api_guide_Variable` 的值。如果``scope``为``None``,通过 :ref:`api_guide_global_scope` 获取全局/默认作用域实例,并从中获取 :ref:`api_guide_Variable` 的值;否则,从指定的``scope``中获取 :ref:`api_guide_Variable` 的值。 + +返回 +::::::::: +Tensor, :ref:`api_guide_Variable` 的值 + +代码示例 +:::::::::: + +.. code-block:: python + + import paddle + import paddle.static as static + import numpy as np + + paddle.enable_static() + + x = static.data(name="x", shape=[10, 10], dtype='float32') + + y = static.nn.fc(x, 10, name='fc') + place = paddle.CPUPlace() + exe = static.Executor(place) + prog = paddle.static.default_main_program() + exe.run(static.default_startup_program()) + inputs = np.ones((10, 10), dtype='float32') + exe.run(prog, feed={'x': inputs}, fetch_list=[y, ]) + path = 'temp/tensor_' + for var in prog.list_vars(): + if var.persistable: + t = var.get_value() + paddle.save(t, path+var.name+'.pdtensor') + + for var in prog.list_vars(): + if var.persistable: + t_load = paddle.load(path+var.name+'.pdtensor') + var.set_value(t_load) + + +.. py:method:: set_value(value, scope=None) + +将``value``设置为 :ref:`api_guide_Variable` 的值。 + +参数 +::::::::: + - value ( Tensor|ndarray ) - :ref:`api_guide_Variable` 的值。 + - scope ( Scope,可选 ) - 将 :ref:`api_guide_Variable` 的值设置到指定的``scope``中。如果``scope``为``None``,通过 :ref:`api_guide_global_scope` 获取全局/默认作用域实例,并将 :ref:`api_guide_Variable` 的值设置到这个用域实例中;否则,将 :ref:`api_guide_Variable` 的值设置到指定的``scope``中。 + +返回 +::::::::: +None + +代码示例 +:::::::::: + +.. code-block:: python + + import paddle + import paddle.static as static + import numpy as np + + paddle.enable_static() + + x = static.data(name="x", shape=[10, 10], dtype='float32') + + y = static.nn.fc(x, 10, name='fc') + place = paddle.CPUPlace() + exe = static.Executor(place) + prog = paddle.static.default_main_program() + exe.run(static.default_startup_program()) + inputs = np.ones((10, 10), dtype='float32') + exe.run(prog, feed={'x': inputs}, fetch_list=[y, ]) + path = 'temp/tensor_' + for var in prog.list_vars(): + if var.persistable: + t = var.get_value() + paddle.save(t, path+var.name+'.pdtensor') + + for var in prog.list_vars(): + if var.persistable: + t_load = paddle.load(path+var.name+'.pdtensor') + var.set_value(t_load) + + 属性 :::::::::::: diff --git a/doc/paddle/api/paddle/framework/io/load_cn.rst b/doc/paddle/api/paddle/framework/io/load_cn.rst index 5f1f437db41..62ff416ff03 100644 --- a/doc/paddle/api/paddle/framework/io/load_cn.rst +++ b/doc/paddle/api/paddle/framework/io/load_cn.rst @@ -8,7 +8,7 @@ load 从指定路径载入可以在paddle中使用的对象实例。 .. note:: - 目前仅支持载入 Layer 或者 Optimizer 的 ``state_dict`` 。 + 目前支持载入:Layer 或者 Optimizer 的 ``state_dict``,Layer对象,Tensor以及包含Tensor的嵌套list、tuple、dict,Program。详细功能及原理在文档 :ref:`_cn_doc_model_save_load` 2.3节。 .. note:: 为了更高效地使用paddle存储的模型参数, ``paddle.load`` 支持从除 ``paddle.save`` 之外的其他save相关API的存储结果中载入 ``state_dict`` ,但是在不同场景中,参数 ``path`` 的形式有所不同: @@ -22,7 +22,7 @@ load 参数 ::::::::: - path (str) – 载入目标对象实例的路径。通常该路径是目标文件的路径,当从用于存储预测模型API的存储结果中载入state_dict时,该路径可能是一个文件前缀或者目录。 - - **config (dict, 可选) - 其他用于兼容的载入配置选项。这些选项将来可能被移除,如果不是必须使用,不推荐使用这些配置选项。默认为 ``None``。目前支持以下配置选项:(1) model_filename (str) - paddle 1.x版本 ``save_inference_model`` 接口存储格式的预测模型文件名,原默认文件名为 ``__model__`` ; (2) params_filename (str) - paddle 1.x版本 ``save_inference_model`` 接口存储格式的参数文件名,没有默认文件名,默认将各个参数分散存储为单独的文件。 + - **config (dict, 可选) - 其他用于兼容的载入配置选项。这些选项将来可能被移除,如果不是必须使用,不推荐使用这些配置选项。默认为 ``None``。目前支持以下配置选项:(1) model_filename (str) - paddle 1.x版本 ``save_inference_model`` 接口存储格式的预测模型文件名,原默认文件名为 ``__model__`` ; (2) params_filename (str) - paddle 1.x版本 ``save_inference_model`` 接口存储格式的参数文件名,没有默认文件名,默认将各个参数分散存储为单独的文件; (3) return_numpy(bool) - 如果被指定为``True``,``load``的结果中的Tensor会被转化为``numpy.ndarray``,默认为``False``。 返回 ::::::::: @@ -33,10 +33,12 @@ Object,一个可以在paddle中使用的对象实例 .. code-block:: python + # example 1: dynamic graph import paddle - emb = paddle.nn.Embedding(10, 10) layer_state_dict = emb.state_dict() + + # save state_dict of emb paddle.save(layer_state_dict, "emb.pdparams") scheduler = paddle.optimizer.lr.NoamDecay( @@ -45,7 +47,45 @@ Object,一个可以在paddle中使用的对象实例 learning_rate=scheduler, parameters=emb.parameters()) opt_state_dict = adam.state_dict() + + # save state_dict of optimizer paddle.save(opt_state_dict, "adam.pdopt") + # save weight of emb + paddle.save(emb.weight, "emb.weight.pdtensor") + # load state_dict of emb load_layer_state_dict = paddle.load("emb.pdparams") + # load state_dict of optimizer load_opt_state_dict = paddle.load("adam.pdopt") + # load weight of emb + load_weight = paddle.load("emb.weight.pdtensor") + + + # example 2: static graph + import paddle + import paddle.static as static + + paddle.enable_static() + + # create network + x = paddle.static.data(name="x", shape=[None, 224], dtype='float32') + z = paddle.static.nn.fc(x, 10) + + place = paddle.CPUPlace() + exe = paddle.static.Executor(place) + exe.run(paddle.static.default_startup_program()) + prog = paddle.static.default_main_program() + for var in prog.list_vars(): + if list(var.shape) == [224, 10]: + tensor = var.get_tensor() + break + + # save/load tensor + path_tensor = 'temp/tensor.pdtensor' + paddle.save(tensor, path_tensor) + load_tensor = paddle.load(path_tensor) + + # save/load state_dict + path_state_dict = 'temp/model.pdparams' + paddle.save(prog.state_dict("param"), path_tensor) + load_state_dict = paddle.load(path_tensor) diff --git a/doc/paddle/api/paddle/framework/io/save_cn.rst b/doc/paddle/api/paddle/framework/io/save_cn.rst index 942ddf57aae..e71ac6fc5de 100644 --- a/doc/paddle/api/paddle/framework/io/save_cn.rst +++ b/doc/paddle/api/paddle/framework/io/save_cn.rst @@ -3,12 +3,12 @@ save ----- -.. py:function:: paddle.save(obj, path, pickle_protocol=2) +.. py:function:: paddle.save(obj, path, protocol=2) 将对象实例obj保存到指定的路径中。 .. note:: - 目前仅支持存储 Layer 或者 Optimizer 的 ``state_dict`` 。 + 目前支持保存:Layer 或者 Optimizer 的 ``state_dict``,Layer对象,Tensor以及包含Tensor的嵌套list、tuple、dict,Program。详细功能及原理在文档 :ref:`_cn_doc_model_save_load` 2.3节。 .. note:: 不同于 ``paddle.jit.save`` ,由于 ``paddle.save`` 的存储结果是单个文件,所以不需要通过添加后缀的方式区分多个存储文件,``paddle.save`` 的输入参数 ``path`` 将直接作为存储结果的文件名而非前缀。为了统一存储文件名的格式,我们推荐使用paddle标椎文件后缀: @@ -20,7 +20,8 @@ save ::::::::: - **obj** (Object) – 要保存的对象实例。 - **path** (str) – 保存对象实例的路径。如果存储到当前路径,输入的path字符串将会作为保存的文件名。 - - **pickle_protocol** (int, 可选) – pickle模块的协议版本,默认值为2,取值范围是[2,4]。 + - **protocol** (int, 可选) – pickle模块的协议版本,默认值为2,取值范围是[2,4]。 + - **configs** (dict, 可选) – 其他配置选项,目前支持以下选项:(1)use_binary_format(bool)- 如果被保存的对象是静态图的Tensor,您可以指定这个参数。如果被指定为``True``,这个Tensor会被保存为由paddle定义的二进制格式的文件;否则这个Tensor被保存为pickle格式。默认为``False``。 返回 ::::::::: @@ -31,10 +32,13 @@ save .. code-block:: python + # example 1: dynamic graph import paddle emb = paddle.nn.Embedding(10, 10) layer_state_dict = emb.state_dict() + + # save state_dict of emb paddle.save(layer_state_dict, "emb.pdparams") scheduler = paddle.optimizer.lr.NoamDecay( @@ -43,4 +47,35 @@ save learning_rate=scheduler, parameters=emb.parameters()) opt_state_dict = adam.state_dict() + + # save state_dict of optimizer paddle.save(opt_state_dict, "adam.pdopt") + # save weight of emb + paddle.save(emb.weight, "emb.weight.pdtensor") + + # example 2: static graph + import paddle + import paddle.static as static + + paddle.enable_static() + + # create network + x = paddle.static.data(name="x", shape=[None, 224], dtype='float32') + z = paddle.static.nn.fc(x, 10) + + place = paddle.CPUPlace() + exe = paddle.static.Executor(place) + exe.run(paddle.static.default_startup_program()) + prog = paddle.static.default_main_program() + for var in prog.list_vars(): + if list(var.shape) == [224, 10]: + tensor = var.get_value() + break + + # save/load tensor + path_tensor = 'temp/tensor.pdtensor' + paddle.save(tensor, path_tensor) + + # save/load state_dict + path_state_dict = 'temp/model.pdparams' + paddle.save(prog.state_dict("param"), path_tensor) diff --git a/doc/paddle/guides/02_paddle2.0_develop/08_model_save_load_cn.rst b/doc/paddle/guides/02_paddle2.0_develop/08_model_save_load_cn.rst index a662f114d64..c39296382e1 100644 --- a/doc/paddle/guides/02_paddle2.0_develop/08_model_save_load_cn.rst +++ b/doc/paddle/guides/02_paddle2.0_develop/08_model_save_load_cn.rst @@ -157,6 +157,23 @@ adam.set_state_dict(opt_state_dict) +2.3 ``paddle.save/load``功能及原理介绍 +------------ + +2.3.1 :ref:`_cn_api_paddle_framework_io_save` 是如何保存``state_dict``,Layer对象,Tensor以及包含Tensor的嵌套list、tuple、dict的呢? +(1)对于``state_dict``保存方式与paddle2.0完全相同,我们将``Tensor``转化为``numpy.ndarray``保存。 +(2)对于其他形式的包含``Tensor``的对象(``Layer``对象,单个``Tensor``以及包含``Tensor``的嵌套``list``、``tuple``、``dict``),在动态图中,将``Tensor``转化为``tuple(Tensor.name, Tensor.numpy())``;在静态图中,将``Tensor``直接转化为``numpy.ndarray``。之所以这样做,是因为当在静态图中使用动态保存的模型时,有时需要``Tensor``的名字因此将名字保存下来,同时,在``load``时区分这个``numpy.ndarray``是由Tenosr转化而来还是本来就是``numpy.ndarray``;保存静态图的``Tensor``时,通常通过``Variable.get_value``得到``Tensor``再使用``paddle.save``保存``Tensor``,此时,``Variable``是有名字的,这个``Tensor``是没有名字的,因此将静态图``Tensor``直接转化为``numpy.ndarray``保存。 + +2.3.2 将``Tensor``转换为``numpy.ndarray``或者``tuple(Tensor.name, Tensor.numpy())``不是可逆编码,为什么还要做这样的转换呢? +(1)我们希望``paddle.save``保存的模型能够不依赖paddle框架就能够被用户解析(pickle格式模型),这样用户可以方便的做调试,轻松的看到保存的参数的数值。其他框架的模型与paddle模型做转化也会容易很多。 +(2)我们希望保存的模型尽量小,只保留了能够满足大多场景的信息(动态图保存名字和数值,静态图只保存数值),如果需要``Tensor``的其他信息(例如``stop_gradient``),可以向被保存的对象中添加这些信息,``load``之后再还原这些信息。 + +2.3.3 什么情况下save与load的结果不一致呢,应该如何避免这种情况发生呢? +以下情况会造成save与load的结果不一致:(1)被保存的对象包含动态图``Tensor``同时包含``tuple(string, numpy.ndarray)``;(2)被保存的对象包含静态图``Tensor``,同时包含``numpy.ndarray``或者``tuple(string, numpy.ndarray)``;(3)被保存的对象只包含``numpy.ndarray``,但是包含``tuple(string, numpy.ndarray)``。之所以这样做,是因为当在静态图中使用动态保存的模型时,有时需要 +针对这些情况我们有以下建议:(1)被保存的对象(包括``Layer``对象中的``ParamBase``),避免包含形如``tuple(string, numpy.ndarray)``的对象;(2)如果被保存的对象包含``numpy.ndarray``,尽量在``load``时设置``return_numpy = True``。(3)只保存``Layer``对象中参数的值和名字,如果需要其他信息(例如``stop_gradient``),请将手动添加这些信息到保存对象中。 + + + 三、模型&参数存储载入(训练部署) ############################ From eb3d9d77e6f8b31551de29fd917b5d65c694fa33 Mon Sep 17 00:00:00 2001 From: WeiXin Date: Tue, 11 May 2021 02:55:44 +0000 Subject: [PATCH 02/18] paddle.save/load2.1 --- doc/paddle/api/paddle/framework/io/load_cn.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/paddle/api/paddle/framework/io/load_cn.rst b/doc/paddle/api/paddle/framework/io/load_cn.rst index 62ff416ff03..56492fe53c4 100644 --- a/doc/paddle/api/paddle/framework/io/load_cn.rst +++ b/doc/paddle/api/paddle/framework/io/load_cn.rst @@ -77,7 +77,7 @@ Object,一个可以在paddle中使用的对象实例 prog = paddle.static.default_main_program() for var in prog.list_vars(): if list(var.shape) == [224, 10]: - tensor = var.get_tensor() + tensor = var.get_value() break # save/load tensor From e8aae0df32d1c481becb4ec60840141d3000dc8a Mon Sep 17 00:00:00 2001 From: WeiXin Date: Thu, 13 May 2021 06:27:57 +0000 Subject: [PATCH 03/18] polish doc --- doc/paddle/api/paddle/framework/io/save_cn.rst | 6 +++++- doc/paddle/faq/save_cn.md | 13 +++++++++++++ .../08_model_save_load_cn.rst | 17 ----------------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/doc/paddle/api/paddle/framework/io/save_cn.rst b/doc/paddle/api/paddle/framework/io/save_cn.rst index e71ac6fc5de..5dc0d45a919 100644 --- a/doc/paddle/api/paddle/framework/io/save_cn.rst +++ b/doc/paddle/api/paddle/framework/io/save_cn.rst @@ -8,7 +8,11 @@ save 将对象实例obj保存到指定的路径中。 .. note:: - 目前支持保存:Layer 或者 Optimizer 的 ``state_dict``,Layer对象,Tensor以及包含Tensor的嵌套list、tuple、dict,Program。详细功能及原理在文档 :ref:`_cn_doc_model_save_load` 2.3节。 + 目前支持保存:Layer 或者 Optimizer 的 ``state_dict``,Layer对象,Tensor以及包含Tensor的嵌套list、tuple、dict,Program。如果您想进一步了解这个API,请参考: + + save_cn.md + .. toctree:: + :maxdepth: 1 .. note:: 不同于 ``paddle.jit.save`` ,由于 ``paddle.save`` 的存储结果是单个文件,所以不需要通过添加后缀的方式区分多个存储文件,``paddle.save`` 的输入参数 ``path`` 将直接作为存储结果的文件名而非前缀。为了统一存储文件名的格式,我们推荐使用paddle标椎文件后缀: diff --git a/doc/paddle/faq/save_cn.md b/doc/paddle/faq/save_cn.md index 526c41eb1af..473f7f45ec1 100644 --- a/doc/paddle/faq/save_cn.md +++ b/doc/paddle/faq/save_cn.md @@ -46,6 +46,19 @@ emb.set_state_dict(para_state_dict) adam.set_state_dict(opti_state_dict) ``` +##### 问题:paddle.save 是如何保存state_dict,Layer对象,Tensor以及包含Tensor的嵌套list、tuple、dict的呢? ++ 答复: +(1)对于``state_dict``保存方式与paddle2.0完全相同,我们将``Tensor``转化为``numpy.ndarray``保存。 +(2)对于其他形式的包含``Tensor``的对象(``Layer``对象,单个``Tensor``以及包含``Tensor``的嵌套``list``、``tuple``、``dict``),在动态图中,将``Tensor``转化为``tuple(Tensor.name, Tensor.numpy())``;在静态图中,将``Tensor``直接转化为``numpy.ndarray``。之所以这样做,是因为当在静态图中使用动态保存的模型时,有时需要``Tensor``的名字因此将名字保存下来,同时,在``load``时区分这个``numpy.ndarray``是由Tenosr转化而来还是本来就是``numpy.ndarray``;保存静态图的``Tensor``时,通常通过``Variable.get_value``得到``Tensor``再使用``paddle.save``保存``Tensor``,此时,``Variable``是有名字的,这个``Tensor``是没有名字的,因此将静态图``Tensor``直接转化为``numpy.ndarray``保存。 + +##### 问题:将Tensor转换为numpy.ndarray或者tuple(Tensor.name, Tensor.numpy())不是惟一可译编码,为什么还要做这样的转换呢? +(1)我们希望``paddle.save``保存的模型能够不依赖paddle框架就能够被用户解析(pickle格式模型),这样用户可以方便的做调试,轻松的看到保存的参数的数值。其他框架的模型与paddle模型做转化也会容易很多。 +(2)我们希望保存的模型尽量小,只保留了能够满足大多场景的信息(动态图保存名字和数值,静态图只保存数值),如果需要``Tensor``的其他信息(例如``stop_gradient``),可以向被保存的对象中添加这些信息,``load``之后再还原这些信息。这样的转换方式可以覆盖绝大多数场景,一些特殊场景也是可以通过一些方法解决的,如下面的问题。 + +##### 问题:什么情况下save与load的结果不一致呢,应该如何避免这种情况发生呢? +以下情况会造成save与load的结果不一致:(1)被保存的对象包含动态图``Tensor``同时包含``tuple(string, numpy.ndarray)``;(2)被保存的对象包含静态图``Tensor``,同时包含``numpy.ndarray``或者``tuple(string, numpy.ndarray)``;(3)被保存的对象只包含``numpy.ndarray``,但是包含``tuple(string, numpy.ndarray)``。 +针对这些情况我们有以下建议:(1)被保存的对象(包括``Layer``对象中的``ParamBase``),避免包含形如``tuple(string, numpy.ndarray)``的对象;(2)如果被保存的对象包含``numpy.ndarray``,尽量在``load``时设置``return_numpy = True``。(3)对于``Layer``对象,只保存参数的值和名字,如果需要其他信息(例如``stop_gradient``),请将手将这些信息打包成`dict`等,一并保存。 + 更多介绍请参考以下API文档: - [paddle.save](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/framework/io/save_cn.html) diff --git a/doc/paddle/guides/02_paddle2.0_develop/08_model_save_load_cn.rst b/doc/paddle/guides/02_paddle2.0_develop/08_model_save_load_cn.rst index c39296382e1..a662f114d64 100644 --- a/doc/paddle/guides/02_paddle2.0_develop/08_model_save_load_cn.rst +++ b/doc/paddle/guides/02_paddle2.0_develop/08_model_save_load_cn.rst @@ -157,23 +157,6 @@ adam.set_state_dict(opt_state_dict) -2.3 ``paddle.save/load``功能及原理介绍 ------------- - -2.3.1 :ref:`_cn_api_paddle_framework_io_save` 是如何保存``state_dict``,Layer对象,Tensor以及包含Tensor的嵌套list、tuple、dict的呢? -(1)对于``state_dict``保存方式与paddle2.0完全相同,我们将``Tensor``转化为``numpy.ndarray``保存。 -(2)对于其他形式的包含``Tensor``的对象(``Layer``对象,单个``Tensor``以及包含``Tensor``的嵌套``list``、``tuple``、``dict``),在动态图中,将``Tensor``转化为``tuple(Tensor.name, Tensor.numpy())``;在静态图中,将``Tensor``直接转化为``numpy.ndarray``。之所以这样做,是因为当在静态图中使用动态保存的模型时,有时需要``Tensor``的名字因此将名字保存下来,同时,在``load``时区分这个``numpy.ndarray``是由Tenosr转化而来还是本来就是``numpy.ndarray``;保存静态图的``Tensor``时,通常通过``Variable.get_value``得到``Tensor``再使用``paddle.save``保存``Tensor``,此时,``Variable``是有名字的,这个``Tensor``是没有名字的,因此将静态图``Tensor``直接转化为``numpy.ndarray``保存。 - -2.3.2 将``Tensor``转换为``numpy.ndarray``或者``tuple(Tensor.name, Tensor.numpy())``不是可逆编码,为什么还要做这样的转换呢? -(1)我们希望``paddle.save``保存的模型能够不依赖paddle框架就能够被用户解析(pickle格式模型),这样用户可以方便的做调试,轻松的看到保存的参数的数值。其他框架的模型与paddle模型做转化也会容易很多。 -(2)我们希望保存的模型尽量小,只保留了能够满足大多场景的信息(动态图保存名字和数值,静态图只保存数值),如果需要``Tensor``的其他信息(例如``stop_gradient``),可以向被保存的对象中添加这些信息,``load``之后再还原这些信息。 - -2.3.3 什么情况下save与load的结果不一致呢,应该如何避免这种情况发生呢? -以下情况会造成save与load的结果不一致:(1)被保存的对象包含动态图``Tensor``同时包含``tuple(string, numpy.ndarray)``;(2)被保存的对象包含静态图``Tensor``,同时包含``numpy.ndarray``或者``tuple(string, numpy.ndarray)``;(3)被保存的对象只包含``numpy.ndarray``,但是包含``tuple(string, numpy.ndarray)``。之所以这样做,是因为当在静态图中使用动态保存的模型时,有时需要 -针对这些情况我们有以下建议:(1)被保存的对象(包括``Layer``对象中的``ParamBase``),避免包含形如``tuple(string, numpy.ndarray)``的对象;(2)如果被保存的对象包含``numpy.ndarray``,尽量在``load``时设置``return_numpy = True``。(3)只保存``Layer``对象中参数的值和名字,如果需要其他信息(例如``stop_gradient``),请将手动添加这些信息到保存对象中。 - - - 三、模型&参数存储载入(训练部署) ############################ From 14658834df0f0106129b24bf34e75fb9be13206e Mon Sep 17 00:00:00 2001 From: WeiXin Date: Thu, 13 May 2021 07:34:29 +0000 Subject: [PATCH 04/18] polish doc --- .../api/paddle/fluid/dygraph/jit/save_cn.rst | 2 +- doc/paddle/api/paddle/framework/io/save_cn.rst | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/doc/paddle/api/paddle/fluid/dygraph/jit/save_cn.rst b/doc/paddle/api/paddle/fluid/dygraph/jit/save_cn.rst index a43efdc2531..e3f7ec37707 100644 --- a/doc/paddle/api/paddle/fluid/dygraph/jit/save_cn.rst +++ b/doc/paddle/api/paddle/fluid/dygraph/jit/save_cn.rst @@ -17,7 +17,7 @@ save - 其他预测库API .. note:: - 当使用 ``paddle.jit.save`` 保存 ``function`` 时, ``function`` 不能包含参数变量。如果您必须保存参数变量,请用Layer封装function,然后按照处理Layer的方式调用相应的API。 + 当使用 ``paddle.jit.save`` 保存 ``function`` 时, ``function`` 不能包含参数变量。如果必须保存参数变量,请用Layer封装function,然后按照处理Layer的方式调用相应的API。 参数 ::::::::: diff --git a/doc/paddle/api/paddle/framework/io/save_cn.rst b/doc/paddle/api/paddle/framework/io/save_cn.rst index 5dc0d45a919..a28fe93f788 100644 --- a/doc/paddle/api/paddle/framework/io/save_cn.rst +++ b/doc/paddle/api/paddle/framework/io/save_cn.rst @@ -8,11 +8,7 @@ save 将对象实例obj保存到指定的路径中。 .. note:: - 目前支持保存:Layer 或者 Optimizer 的 ``state_dict``,Layer对象,Tensor以及包含Tensor的嵌套list、tuple、dict,Program。如果您想进一步了解这个API,请参考: - - save_cn.md - .. toctree:: - :maxdepth: 1 + 目前支持保存:Layer 或者 Optimizer 的 ``state_dict``,Layer对象,Tensor以及包含Tensor的嵌套list、tuple、dict,Program。 .. note:: 不同于 ``paddle.jit.save`` ,由于 ``paddle.save`` 的存储结果是单个文件,所以不需要通过添加后缀的方式区分多个存储文件,``paddle.save`` 的输入参数 ``path`` 将直接作为存储结果的文件名而非前缀。为了统一存储文件名的格式,我们推荐使用paddle标椎文件后缀: @@ -20,12 +16,19 @@ save 2. 对于 ``Optimizer.state_dict`` ,推荐使用后缀 ``.pdopt`` 。 具体示例请参考API的代码示例。 + +如果想进一步了解这个API,请参考: + + .. toctree:: + :maxdepth: 1 + + ../../../../faq/save_cn.md 参数 ::::::::: - **obj** (Object) – 要保存的对象实例。 - **path** (str) – 保存对象实例的路径。如果存储到当前路径,输入的path字符串将会作为保存的文件名。 - **protocol** (int, 可选) – pickle模块的协议版本,默认值为2,取值范围是[2,4]。 - - **configs** (dict, 可选) – 其他配置选项,目前支持以下选项:(1)use_binary_format(bool)- 如果被保存的对象是静态图的Tensor,您可以指定这个参数。如果被指定为``True``,这个Tensor会被保存为由paddle定义的二进制格式的文件;否则这个Tensor被保存为pickle格式。默认为``False``。 + - **configs** (dict, 可选) – 其他配置选项,目前支持以下选项:(1)use_binary_format(bool)- 如果被保存的对象是静态图的Tensor,你可以指定这个参数。如果被指定为``True``,这个Tensor会被保存为由paddle定义的二进制格式的文件;否则这个Tensor被保存为pickle格式。默认为``False``。 返回 ::::::::: From ba1a24abcbe17cc1142fd1ca19b2edbf1cddd6a0 Mon Sep 17 00:00:00 2001 From: WeiXin Date: Thu, 13 May 2021 07:58:47 +0000 Subject: [PATCH 05/18] polish doc --- doc/paddle/api/paddle/fluid/framework/Program_cn.rst | 4 ++-- doc/paddle/api/paddle/fluid/framework/Variable_cn.rst | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/paddle/api/paddle/fluid/framework/Program_cn.rst b/doc/paddle/api/paddle/fluid/framework/Program_cn.rst index 4eb4a3401bb..f0f9f8506bd 100644 --- a/doc/paddle/api/paddle/fluid/framework/Program_cn.rst +++ b/doc/paddle/api/paddle/fluid/framework/Program_cn.rst @@ -477,7 +477,7 @@ list[ :ref:`api_guide_parameter` ],一个包含当前Program中所有参数的 参数 ::::::::: - mode (str, 可选) - 获取何种参数和可持久性buffers。目前支持以下选项: (1) 'opt':获得优化器的参数和可持久性buffers放在dict结构中; (2) 'param':获得组网中的参数和可持久性buffers放在dict结构中,不包含优化器中的参数和可持久性buffers; (3) 'all':获得组网和优化器中的参数和可持久性buffers放在dict结构中;默认值为'all'。 - - scope (Scope, 可选) - 如果scope为``None``,通过 :ref:`api_guide_global_scope` 获取全局/默认作用域实例,并从中获取``state_dict``;否则从指定的``scope``获取``state_dict``。默认值为``None``。 + - scope (Scope, 可选) - 如果scope为 ``None`` ,通过 :ref:`api_fluid_executor_global_scope` 获取全局/默认作用域实例,并从中获取 ``state_dict`` ;否则从指定的 ``scope`` 获取 ``state_dict`` 。默认值为 ``None`` 。 返回 ::::::::: @@ -512,7 +512,7 @@ dict, 包含所有参数和可持久行buffers的dict 参数 ::::::::: - state_dict (dict) - 包含参数和可持久性buffers的字典。键值是参数和可持久性buffers的名字,值为参数和可持久性buffers。 - - scope (Scope, 可选) - 如果scope为``None``,通过 :ref:`api_guide_global_scope` 获取全局/默认作用域实例,并将``state_dict``中参数和可持久性buffers设置到这个作用域中;否则将``state_dict``设置到指定的``scope``中。默认值为``None``。 + - scope (Scope, 可选) - 如果scope为 ``None`` ,通过 :ref:`api_fluid_executor_global_scope` 获取全局/默认作用域实例,并将 ``state_dict`` 中参数和可持久性buffers设置到这个作用域中;否则将 ``state_dict`` 设置到指定的 ``scope`` 中。默认值为 ``None`` 。 返回 ::::::::: diff --git a/doc/paddle/api/paddle/fluid/framework/Variable_cn.rst b/doc/paddle/api/paddle/fluid/framework/Variable_cn.rst index ecc1c80d921..a4ae20b3c53 100644 --- a/doc/paddle/api/paddle/fluid/framework/Variable_cn.rst +++ b/doc/paddle/api/paddle/fluid/framework/Variable_cn.rst @@ -120,7 +120,7 @@ Variable 参数 ::::::::: - - scope ( Scope,可选 ) - 从指定的``scope``中获取 :ref:`api_guide_Variable` 的值。如果``scope``为``None``,通过 :ref:`api_guide_global_scope` 获取全局/默认作用域实例,并从中获取 :ref:`api_guide_Variable` 的值;否则,从指定的``scope``中获取 :ref:`api_guide_Variable` 的值。 + - scope ( Scope,可选 ) - 从指定的 ``scope`` 中获取 :ref:`api_guide_Variable` 的值。如果 ``scope`` 为 ``None`` ,通过 :ref:`api_fluid_executor_global_scope` 获取全局/默认作用域实例,并从中获取 :ref:`api_guide_Variable` 的值;否则,从指定的 ``scope`` 中获取 :ref:`api_guide_Variable` 的值。 返回 ::::::::: @@ -160,12 +160,12 @@ Tensor, :ref:`api_guide_Variable` 的值 .. py:method:: set_value(value, scope=None) -将``value``设置为 :ref:`api_guide_Variable` 的值。 +将 ``value`` 设置为 :ref:`api_guide_Variable` 的值。 参数 ::::::::: - value ( Tensor|ndarray ) - :ref:`api_guide_Variable` 的值。 - - scope ( Scope,可选 ) - 将 :ref:`api_guide_Variable` 的值设置到指定的``scope``中。如果``scope``为``None``,通过 :ref:`api_guide_global_scope` 获取全局/默认作用域实例,并将 :ref:`api_guide_Variable` 的值设置到这个用域实例中;否则,将 :ref:`api_guide_Variable` 的值设置到指定的``scope``中。 + - scope ( Scope,可选 ) - 将 :ref:`api_guide_Variable` 的值设置到指定的 ``scope`` 中。如果 ``scope`` 为 ``None`` ,通过 :ref:`api_fluid_executor_global_scope` 获取全局/默认作用域实例,并将 :ref:`api_guide_Variable` 的值设置到这个用域实例中;否则,将 :ref:`api_guide_Variable` 的值设置到指定的 ``scope`` 中。 返回 ::::::::: From e0669b22bf3efdda30e849de1e9f87ab29a48448 Mon Sep 17 00:00:00 2001 From: WeiXin Date: Thu, 13 May 2021 08:22:18 +0000 Subject: [PATCH 06/18] polish doc --- doc/paddle/faq/save_cn.md | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/doc/paddle/faq/save_cn.md b/doc/paddle/faq/save_cn.md index 473f7f45ec1..bbec113107f 100644 --- a/doc/paddle/faq/save_cn.md +++ b/doc/paddle/faq/save_cn.md @@ -48,16 +48,29 @@ adam.set_state_dict(opti_state_dict) ##### 问题:paddle.save 是如何保存state_dict,Layer对象,Tensor以及包含Tensor的嵌套list、tuple、dict的呢? + 答复: -(1)对于``state_dict``保存方式与paddle2.0完全相同,我们将``Tensor``转化为``numpy.ndarray``保存。 -(2)对于其他形式的包含``Tensor``的对象(``Layer``对象,单个``Tensor``以及包含``Tensor``的嵌套``list``、``tuple``、``dict``),在动态图中,将``Tensor``转化为``tuple(Tensor.name, Tensor.numpy())``;在静态图中,将``Tensor``直接转化为``numpy.ndarray``。之所以这样做,是因为当在静态图中使用动态保存的模型时,有时需要``Tensor``的名字因此将名字保存下来,同时,在``load``时区分这个``numpy.ndarray``是由Tenosr转化而来还是本来就是``numpy.ndarray``;保存静态图的``Tensor``时,通常通过``Variable.get_value``得到``Tensor``再使用``paddle.save``保存``Tensor``,此时,``Variable``是有名字的,这个``Tensor``是没有名字的,因此将静态图``Tensor``直接转化为``numpy.ndarray``保存。 + 1. 对于``state_dict``保存方式与paddle2.0完全相同,我们将``Tensor``转化为``numpy.ndarray``保存。 + + 2. 对于其他形式的包含``Tensor``的对象(``Layer``对象,单个``Tensor``以及包含``Tensor``的嵌套``list``、``tuple``、``dict``),在动态图中,将``Tensor``转化为``tuple(Tensor.name, Tensor.numpy())``;在静态图中,将``Tensor``直接转化为``numpy.ndarray``。之所以这样做,是因为当在静态图中使用动态保存的模型时,有时需要``Tensor``的名字因此将名字保存下来,同时,在``load``时区分这个``numpy.ndarray``是由Tenosr转化而来还是本来就是``numpy.ndarray``;保存静态图的``Tensor``时,通常通过``Variable.get_value``得到``Tensor``再使用``paddle.save``保存``Tensor``,此时,``Variable``是有名字的,这个``Tensor``是没有名字的,因此将静态图``Tensor``直接转化为``numpy.ndarray``保存。 ##### 问题:将Tensor转换为numpy.ndarray或者tuple(Tensor.name, Tensor.numpy())不是惟一可译编码,为什么还要做这样的转换呢? -(1)我们希望``paddle.save``保存的模型能够不依赖paddle框架就能够被用户解析(pickle格式模型),这样用户可以方便的做调试,轻松的看到保存的参数的数值。其他框架的模型与paddle模型做转化也会容易很多。 -(2)我们希望保存的模型尽量小,只保留了能够满足大多场景的信息(动态图保存名字和数值,静态图只保存数值),如果需要``Tensor``的其他信息(例如``stop_gradient``),可以向被保存的对象中添加这些信息,``load``之后再还原这些信息。这样的转换方式可以覆盖绝大多数场景,一些特殊场景也是可以通过一些方法解决的,如下面的问题。 ++ 答复: + + 1. 我们希望``paddle.save``保存的模型能够不依赖paddle框架就能够被用户解析(pickle格式模型),这样用户可以方便的做调试,轻松的看到保存的参数的数值。其他框架的模型与paddle模型做转化也会容易很多。 + + 2. 我们希望保存的模型尽量小,只保留了能够满足大多场景的信息(动态图保存名字和数值,静态图只保存数值),如果需要``Tensor``的其他信息(例如``stop_gradient``),可以向被保存的对象中添加这些信息,``load``之后再还原这些信息。这样的转换方式可以覆盖绝大多数场景,一些特殊场景也是可以通过一些方法解决的,如下面的问题。 ##### 问题:什么情况下save与load的结果不一致呢,应该如何避免这种情况发生呢? -以下情况会造成save与load的结果不一致:(1)被保存的对象包含动态图``Tensor``同时包含``tuple(string, numpy.ndarray)``;(2)被保存的对象包含静态图``Tensor``,同时包含``numpy.ndarray``或者``tuple(string, numpy.ndarray)``;(3)被保存的对象只包含``numpy.ndarray``,但是包含``tuple(string, numpy.ndarray)``。 -针对这些情况我们有以下建议:(1)被保存的对象(包括``Layer``对象中的``ParamBase``),避免包含形如``tuple(string, numpy.ndarray)``的对象;(2)如果被保存的对象包含``numpy.ndarray``,尽量在``load``时设置``return_numpy = True``。(3)对于``Layer``对象,只保存参数的值和名字,如果需要其他信息(例如``stop_gradient``),请将手将这些信息打包成`dict`等,一并保存。 ++ 答复: + + 以下情况会造成save与load的结果不一致: + 1. 被保存的对象包含动态图``Tensor``同时包含``tuple(string, numpy.ndarray)``; + 2. 被保存的对象包含静态图``Tensor``,同时包含``numpy.ndarray``或者``tuple(string, numpy.ndarray)``; + 3. 被保存的对象只包含``numpy.ndarray``,但是包含``tuple(string, numpy.ndarray)``。 + + 针对这些情况我们有以下建议: + 1. 被保存的对象(包括``Layer``对象中的``ParamBase``),避免包含形如``tuple(string, numpy.ndarray)``的对象; + 2. 如果被保存的对象包含``numpy.ndarray``,尽量在``load``时设置``return_numpy = True``。 + 3. 对于``Layer``对象,只保存参数的值和名字,如果需要其他信息(例如``stop_gradient``),请将手将这些信息打包成`dict`等,一并保存。 更多介绍请参考以下API文档: From 39f43133fbb3d8e8ba7fe5c34f1d3e6345c27e00 Mon Sep 17 00:00:00 2001 From: WeiXin Date: Thu, 13 May 2021 09:17:42 +0000 Subject: [PATCH 07/18] polish doc --- doc/paddle/api/paddle/fluid/framework/Program_cn.rst | 4 ++-- doc/paddle/api/paddle/fluid/framework/Variable_cn.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/paddle/api/paddle/fluid/framework/Program_cn.rst b/doc/paddle/api/paddle/fluid/framework/Program_cn.rst index f0f9f8506bd..31ce1022455 100644 --- a/doc/paddle/api/paddle/fluid/framework/Program_cn.rst +++ b/doc/paddle/api/paddle/fluid/framework/Program_cn.rst @@ -477,7 +477,7 @@ list[ :ref:`api_guide_parameter` ],一个包含当前Program中所有参数的 参数 ::::::::: - mode (str, 可选) - 获取何种参数和可持久性buffers。目前支持以下选项: (1) 'opt':获得优化器的参数和可持久性buffers放在dict结构中; (2) 'param':获得组网中的参数和可持久性buffers放在dict结构中,不包含优化器中的参数和可持久性buffers; (3) 'all':获得组网和优化器中的参数和可持久性buffers放在dict结构中;默认值为'all'。 - - scope (Scope, 可选) - 如果scope为 ``None`` ,通过 :ref:`api_fluid_executor_global_scope` 获取全局/默认作用域实例,并从中获取 ``state_dict`` ;否则从指定的 ``scope`` 获取 ``state_dict`` 。默认值为 ``None`` 。 + - scope (Scope, 可选) - 如果scope为 ``None`` ,通过 `paddle.static.global_scope()` 获取全局/默认作用域实例,并从中获取 ``state_dict`` ;否则从指定的 ``scope`` 获取 ``state_dict`` 。默认值为 ``None`` 。 返回 ::::::::: @@ -512,7 +512,7 @@ dict, 包含所有参数和可持久行buffers的dict 参数 ::::::::: - state_dict (dict) - 包含参数和可持久性buffers的字典。键值是参数和可持久性buffers的名字,值为参数和可持久性buffers。 - - scope (Scope, 可选) - 如果scope为 ``None`` ,通过 :ref:`api_fluid_executor_global_scope` 获取全局/默认作用域实例,并将 ``state_dict`` 中参数和可持久性buffers设置到这个作用域中;否则将 ``state_dict`` 设置到指定的 ``scope`` 中。默认值为 ``None`` 。 + - scope (Scope, 可选) - 如果scope为 ``None`` ,通过 `paddle.static.global_scope()` 获取全局/默认作用域实例,并将 ``state_dict`` 中参数和可持久性buffers设置到这个作用域中;否则将 ``state_dict`` 设置到指定的 ``scope`` 中。默认值为 ``None`` 。 返回 ::::::::: diff --git a/doc/paddle/api/paddle/fluid/framework/Variable_cn.rst b/doc/paddle/api/paddle/fluid/framework/Variable_cn.rst index a4ae20b3c53..fe414142732 100644 --- a/doc/paddle/api/paddle/fluid/framework/Variable_cn.rst +++ b/doc/paddle/api/paddle/fluid/framework/Variable_cn.rst @@ -120,7 +120,7 @@ Variable 参数 ::::::::: - - scope ( Scope,可选 ) - 从指定的 ``scope`` 中获取 :ref:`api_guide_Variable` 的值。如果 ``scope`` 为 ``None`` ,通过 :ref:`api_fluid_executor_global_scope` 获取全局/默认作用域实例,并从中获取 :ref:`api_guide_Variable` 的值;否则,从指定的 ``scope`` 中获取 :ref:`api_guide_Variable` 的值。 + - scope ( Scope,可选 ) - 从指定的 ``scope`` 中获取 :ref:`api_guide_Variable` 的值。如果 ``scope`` 为 ``None`` ,通过 `paddle.static.global_scope()` 获取全局/默认作用域实例,并从中获取 :ref:`api_guide_Variable` 的值;否则,从指定的 ``scope`` 中获取 :ref:`api_guide_Variable` 的值。 返回 ::::::::: @@ -165,7 +165,7 @@ Tensor, :ref:`api_guide_Variable` 的值 参数 ::::::::: - value ( Tensor|ndarray ) - :ref:`api_guide_Variable` 的值。 - - scope ( Scope,可选 ) - 将 :ref:`api_guide_Variable` 的值设置到指定的 ``scope`` 中。如果 ``scope`` 为 ``None`` ,通过 :ref:`api_fluid_executor_global_scope` 获取全局/默认作用域实例,并将 :ref:`api_guide_Variable` 的值设置到这个用域实例中;否则,将 :ref:`api_guide_Variable` 的值设置到指定的 ``scope`` 中。 + - scope ( Scope,可选 ) - 将 :ref:`api_guide_Variable` 的值设置到指定的 ``scope`` 中。如果 ``scope`` 为 ``None`` ,通过 `paddle.static.global_scope()` 获取全局/默认作用域实例,并将 :ref:`api_guide_Variable` 的值设置到这个用域实例中;否则,将 :ref:`api_guide_Variable` 的值设置到指定的 ``scope`` 中。 返回 ::::::::: From 202a9d07510d92eb1bffea8918e207d9a539704d Mon Sep 17 00:00:00 2001 From: WeiXin Date: Fri, 14 May 2021 04:53:57 +0000 Subject: [PATCH 08/18] edit doc according comment --- .../api/paddle/fluid/framework/Program_cn.rst | 10 +-- .../api/paddle/framework/io/load_cn.rst | 64 ++++++++++++++++--- .../api/paddle/framework/io/save_cn.rst | 48 +++++++++++++- doc/paddle/faq/save_cn.md | 15 +++++ 4 files changed, 120 insertions(+), 17 deletions(-) diff --git a/doc/paddle/api/paddle/fluid/framework/Program_cn.rst b/doc/paddle/api/paddle/fluid/framework/Program_cn.rst index 31ce1022455..80340011bd4 100644 --- a/doc/paddle/api/paddle/fluid/framework/Program_cn.rst +++ b/doc/paddle/api/paddle/fluid/framework/Program_cn.rst @@ -472,16 +472,16 @@ list[ :ref:`api_guide_parameter` ],一个包含当前Program中所有参数的 .. py:method:: state_dict(mode='all', scope=None) -获取当前层及其子层的所有参数和可持久性buffers。并将所有参数和buffers存放在dict结构中。 +获取当前 ``Program`` 持久性变量。并将所有持久性变量s存放在dict结构中。 参数 ::::::::: - - mode (str, 可选) - 获取何种参数和可持久性buffers。目前支持以下选项: (1) 'opt':获得优化器的参数和可持久性buffers放在dict结构中; (2) 'param':获得组网中的参数和可持久性buffers放在dict结构中,不包含优化器中的参数和可持久性buffers; (3) 'all':获得组网和优化器中的参数和可持久性buffers放在dict结构中;默认值为'all'。 + - mode (str, 可选) - 获取何种持久性变量。目前支持以下选项: (1) 'opt':获得优化器的持久性变量放在dict结构中; (2) 'param':获得组网中的持久性变量放在dict结构中,不包含优化器中的持久性变量; (3) 'all':获得组网和优化器中的持久性变量放在dict结构中;默认值为'all'。 - scope (Scope, 可选) - 如果scope为 ``None`` ,通过 `paddle.static.global_scope()` 获取全局/默认作用域实例,并从中获取 ``state_dict`` ;否则从指定的 ``scope`` 获取 ``state_dict`` 。默认值为 ``None`` 。 返回 ::::::::: -dict, 包含所有参数和可持久行buffers的dict +dict, 包含持久性变量的dict,键值是持久性变量的名字,值为持久性变量。 代码示例 ::::::::: @@ -507,11 +507,11 @@ dict, 包含所有参数和可持久行buffers的dict .. py:method:: set_state_dict(state_dict, scope=None) -获取当前层及其子层的所有参数和可持久性buffers。并将所有参数和buffers存放在dict结构中。 +将 ``state_dict`` 中的持久性变量设置到 ``Program`` 中。 参数 ::::::::: - - state_dict (dict) - 包含参数和可持久性buffers的字典。键值是参数和可持久性buffers的名字,值为参数和可持久性buffers。 + - state_dict (dict) - 包含持久性变量的字典。键值是持久性变量的名字,值为持久性变量。 - scope (Scope, 可选) - 如果scope为 ``None`` ,通过 `paddle.static.global_scope()` 获取全局/默认作用域实例,并将 ``state_dict`` 中参数和可持久性buffers设置到这个作用域中;否则将 ``state_dict`` 设置到指定的 ``scope`` 中。默认值为 ``None`` 。 返回 diff --git a/doc/paddle/api/paddle/framework/io/load_cn.rst b/doc/paddle/api/paddle/framework/io/load_cn.rst index 56492fe53c4..1c66357645f 100644 --- a/doc/paddle/api/paddle/framework/io/load_cn.rst +++ b/doc/paddle/api/paddle/framework/io/load_cn.rst @@ -8,16 +8,15 @@ load 从指定路径载入可以在paddle中使用的对象实例。 .. note:: - 目前支持载入:Layer 或者 Optimizer 的 ``state_dict``,Layer对象,Tensor以及包含Tensor的嵌套list、tuple、dict,Program。详细功能及原理在文档 :ref:`_cn_doc_model_save_load` 2.3节。 + 目前支持载入:Layer 或者 Optimizer 的 ``state_dict``,Layer对象,Tensor以及包含Tensor的嵌套list、tuple、dict,Program。 -.. note:: - 为了更高效地使用paddle存储的模型参数, ``paddle.load`` 支持从除 ``paddle.save`` 之外的其他save相关API的存储结果中载入 ``state_dict`` ,但是在不同场景中,参数 ``path`` 的形式有所不同: - 1. 从 ``paddle.static.save`` 或者 ``paddle.Model().save(training=True)`` 的保存结果载入: ``path`` 需要是完整的文件名,例如 ``model.pdparams`` 或者 ``model.opt`` ; - 2. 从 ``paddle.jit.save`` 或者 ``paddle.static.save_inference_model`` 或者 ``paddle.Model().save(training=False)`` 的保存结果载入: ``path`` 需要是路径前缀, 例如 ``model/mnist`` , ``paddle.load`` 会从 ``mnist.pdmodel`` 和 ``mnist.pdiparams`` 中解析 ``state_dict`` 的信息并返回。 - 3. 从paddle 1.x API ``paddle.fluid.io.save_inference_model`` 或者 ``paddle.fluid.io.save_params/save_persistables`` 的保存结果载入: ``path`` 需要是目录,例如 ``model`` ,此处model是一个文件夹路径。 -.. note:: - 如果从 ``paddle.static.save`` 或者 ``paddle.static.save_inference_model`` 等静态图API的存储结果中载入 ``state_dict`` ,动态图模式下参数的结构性变量名将无法被恢复。在将载入的 ``state_dict`` 配置到当前Layer中时,需要配置 ``Layer.set_state_dict`` 的参数 ``use_structured_name=False`` 。 +如果想进一步了解这个API,请参考: + + .. toctree:: + :maxdepth: 1 + + ../../../../faq/save_cn.md 参数 ::::::::: @@ -61,7 +60,39 @@ Object,一个可以在paddle中使用的对象实例 load_weight = paddle.load("emb.weight.pdtensor") - # example 2: static graph + # example 2: Load multiple state_dict at the same time + from paddle import nn + from paddle.optimizer import Adam + + layer = paddle.nn.Linear(3, 4) + adam = Adam(learning_rate=0.001, parameters=layer.parameters()) + obj = {'model': layer.state_dict(), 'opt': adam.state_dict(), 'epoch': 100} + path = 'example/model.pdparams' + paddle.save(obj, path) + obj_load = paddle.load(path) + + + # example 3: Load layer + import paddle + from paddle import nn + + class LinearNet(nn.Layer): + def __init__(self): + super(LinearNet, self).__init__() + self._linear = nn.Linear(224, 10) + + def forward(self, x): + return self._linear(x) + + inps = paddle.randn([1, 224], dtype='float32') + layer = LinearNet() + layer.eval() + path = "example/layer.pdmodel" + paddle.save(layer,path) + layer_load=paddle.load(path) + + + # example 4: static graph import paddle import paddle.static as static @@ -89,3 +120,18 @@ Object,一个可以在paddle中使用的对象实例 path_state_dict = 'temp/model.pdparams' paddle.save(prog.state_dict("param"), path_tensor) load_state_dict = paddle.load(path_tensor) + + + # example 5: load program + import paddle + + paddle.enable_static() + + data = paddle.static.data( + name='x_static_save', shape=(None, 224), dtype='float32') + y_static = z = paddle.static.nn.fc(data, 10) + main_program = paddle.static.default_main_program() + path = "example/main_program.pdmodel" + paddle.save(main_program, path) + load_main = paddle.load(path) + print(load_main) diff --git a/doc/paddle/api/paddle/framework/io/save_cn.rst b/doc/paddle/api/paddle/framework/io/save_cn.rst index a28fe93f788..75c2a8843fa 100644 --- a/doc/paddle/api/paddle/framework/io/save_cn.rst +++ b/doc/paddle/api/paddle/framework/io/save_cn.rst @@ -17,12 +17,13 @@ save 具体示例请参考API的代码示例。 -如果想进一步了解这个API,请参考: +遇到使用问题,请参考: .. toctree:: :maxdepth: 1 ../../../../faq/save_cn.md + 参数 ::::::::: - **obj** (Object) – 要保存的对象实例。 @@ -41,7 +42,6 @@ save # example 1: dynamic graph import paddle - emb = paddle.nn.Embedding(10, 10) layer_state_dict = emb.state_dict() @@ -60,7 +60,37 @@ save # save weight of emb paddle.save(emb.weight, "emb.weight.pdtensor") - # example 2: static graph + # example 2: Save multiple state_dict at the same time + from paddle import nn + from paddle.optimizer import Adam + + layer = paddle.nn.Linear(3, 4) + adam = Adam(learning_rate=0.001, parameters=layer.parameters()) + obj = {'model': layer.state_dict(), 'opt': adam.state_dict(), 'epoch': 100} + path = 'example/model.pdparams' + paddle.save(obj, path) + + + # example 3: Save layer + import paddle + from paddle import nn + + class LinearNet(nn.Layer): + def __init__(self): + super(LinearNet, self).__init__() + self._linear = nn.Linear(224, 10) + + def forward(self, x): + return self._linear(x) + + inps = paddle.randn([1, 224], dtype='float32') + layer = LinearNet() + layer.eval() + path = "example/layer.pdmodel" + paddle.save(layer,path) + + + # example 4: static graph import paddle import paddle.static as static @@ -86,3 +116,15 @@ save # save/load state_dict path_state_dict = 'temp/model.pdparams' paddle.save(prog.state_dict("param"), path_tensor) + + # example 5: save program + import paddle + + paddle.enable_static() + + data = paddle.static.data( + name='x_static_save', shape=(None, 224), dtype='float32') + y_static = z = paddle.static.nn.fc(data, 10) + main_program = paddle.static.default_main_program() + path = "example/main_program.pdmodel" + paddle.save(main_program, path) diff --git a/doc/paddle/faq/save_cn.md b/doc/paddle/faq/save_cn.md index bbec113107f..563e6c82df6 100644 --- a/doc/paddle/faq/save_cn.md +++ b/doc/paddle/faq/save_cn.md @@ -46,11 +46,26 @@ emb.set_state_dict(para_state_dict) adam.set_state_dict(opti_state_dict) ``` +##### 问题:paddle.load可以加载哪些API产生的模型? ++ 答复: + + 为了更高效地使用paddle存储的模型参数, ``paddle.load`` 支持从除 ``paddle.save`` 之外的其他save相关API的存储结果中载入 ``state_dict`` ,但是在不同场景中,参数 ``path`` 的形式有所不同: + + 1. 从 ``paddle.static.save`` 或者 ``paddle.Model().save(training=True)`` 的保存结果载入: ``path`` 需要是完整的文件名,例如 ``model.pdparams`` 或者 ``model.opt`` ; + + 2. 从 ``paddle.jit.save`` 或者 ``paddle.static.save_inference_model`` 或者 ``paddle.Model().save(training=False)`` 的保存结果载入: ``path`` 需要是路径前缀, 例如 ``model/mnist`` , ``paddle.load`` 会从 ``mnist.pdmodel`` 和 ``mnist.pdiparams`` 中解析 ``state_dict`` 的信息并返回。 + + 3. 从paddle 1.x API ``paddle.fluid.io.save_inference_model`` 或者 ``paddle.fluid.io.save_params/save_persistables`` 的保存结果载入: ``path`` 需要是目录,例如 ``model`` ,此处model是一个文件夹路径。 + + + 需要注意的是,如果从 ``paddle.static.save`` 或者 ``paddle.static.save_inference_model`` 等静态图API的存储结果中载入 ``state_dict`` ,动态图模式下参数的结构性变量名将无法被恢复。在将载入的 ``state_dict`` 配置到当前Layer中时,需要配置 ``Layer.set_state_dict`` 的参数 ``use_structured_name=False`` 。 + ##### 问题:paddle.save 是如何保存state_dict,Layer对象,Tensor以及包含Tensor的嵌套list、tuple、dict的呢? + 答复: 1. 对于``state_dict``保存方式与paddle2.0完全相同,我们将``Tensor``转化为``numpy.ndarray``保存。 2. 对于其他形式的包含``Tensor``的对象(``Layer``对象,单个``Tensor``以及包含``Tensor``的嵌套``list``、``tuple``、``dict``),在动态图中,将``Tensor``转化为``tuple(Tensor.name, Tensor.numpy())``;在静态图中,将``Tensor``直接转化为``numpy.ndarray``。之所以这样做,是因为当在静态图中使用动态保存的模型时,有时需要``Tensor``的名字因此将名字保存下来,同时,在``load``时区分这个``numpy.ndarray``是由Tenosr转化而来还是本来就是``numpy.ndarray``;保存静态图的``Tensor``时,通常通过``Variable.get_value``得到``Tensor``再使用``paddle.save``保存``Tensor``,此时,``Variable``是有名字的,这个``Tensor``是没有名字的,因此将静态图``Tensor``直接转化为``numpy.ndarray``保存。 + > 此处动态图Tensor和静态图Tensor是不相同的,动态图Tensor有name、stop_gradient等属性;而静态图的Tensor是比动态图Tensor轻量级的,只包含place等基本信息,不包含名字等。 ##### 问题:将Tensor转换为numpy.ndarray或者tuple(Tensor.name, Tensor.numpy())不是惟一可译编码,为什么还要做这样的转换呢? + 答复: From b4dfc6302500a6d64e53a80ff93b4c0e10471b25 Mon Sep 17 00:00:00 2001 From: WeiXin Date: Fri, 14 May 2021 04:58:37 +0000 Subject: [PATCH 09/18] polish doc --- doc/paddle/api/paddle/framework/io/load_cn.rst | 6 +++++- doc/paddle/api/paddle/framework/io/save_cn.rst | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/doc/paddle/api/paddle/framework/io/load_cn.rst b/doc/paddle/api/paddle/framework/io/load_cn.rst index 1c66357645f..e89f6883cbd 100644 --- a/doc/paddle/api/paddle/framework/io/load_cn.rst +++ b/doc/paddle/api/paddle/framework/io/load_cn.rst @@ -59,6 +59,7 @@ Object,一个可以在paddle中使用的对象实例 # load weight of emb load_weight = paddle.load("emb.weight.pdtensor") +.. code-block:: python # example 2: Load multiple state_dict at the same time from paddle import nn @@ -71,6 +72,7 @@ Object,一个可以在paddle中使用的对象实例 paddle.save(obj, path) obj_load = paddle.load(path) +.. code-block:: python # example 3: Load layer import paddle @@ -91,7 +93,8 @@ Object,一个可以在paddle中使用的对象实例 paddle.save(layer,path) layer_load=paddle.load(path) - +.. code-block:: python + # example 4: static graph import paddle import paddle.static as static @@ -121,6 +124,7 @@ Object,一个可以在paddle中使用的对象实例 paddle.save(prog.state_dict("param"), path_tensor) load_state_dict = paddle.load(path_tensor) +.. code-block:: python # example 5: load program import paddle diff --git a/doc/paddle/api/paddle/framework/io/save_cn.rst b/doc/paddle/api/paddle/framework/io/save_cn.rst index 75c2a8843fa..39e1ff19313 100644 --- a/doc/paddle/api/paddle/framework/io/save_cn.rst +++ b/doc/paddle/api/paddle/framework/io/save_cn.rst @@ -60,6 +60,9 @@ save # save weight of emb paddle.save(emb.weight, "emb.weight.pdtensor") + +.. code-block:: python + # example 2: Save multiple state_dict at the same time from paddle import nn from paddle.optimizer import Adam @@ -71,6 +74,8 @@ save paddle.save(obj, path) +.. code-block:: python + # example 3: Save layer import paddle from paddle import nn @@ -90,6 +95,8 @@ save paddle.save(layer,path) +.. code-block:: python + # example 4: static graph import paddle import paddle.static as static @@ -117,6 +124,9 @@ save path_state_dict = 'temp/model.pdparams' paddle.save(prog.state_dict("param"), path_tensor) + +.. code-block:: python + # example 5: save program import paddle From 2a0403ec3f1fc149dccdbb211024c18d9d6c1f13 Mon Sep 17 00:00:00 2001 From: WeiXin Date: Fri, 14 May 2021 06:31:52 +0000 Subject: [PATCH 10/18] delete save layer --- .../api/paddle/framework/io/load_cn.rst | 24 ++---------------- .../api/paddle/framework/io/save_cn.rst | 25 ++----------------- 2 files changed, 4 insertions(+), 45 deletions(-) diff --git a/doc/paddle/api/paddle/framework/io/load_cn.rst b/doc/paddle/api/paddle/framework/io/load_cn.rst index e89f6883cbd..a5949e07e05 100644 --- a/doc/paddle/api/paddle/framework/io/load_cn.rst +++ b/doc/paddle/api/paddle/framework/io/load_cn.rst @@ -72,30 +72,10 @@ Object,一个可以在paddle中使用的对象实例 paddle.save(obj, path) obj_load = paddle.load(path) -.. code-block:: python - - # example 3: Load layer - import paddle - from paddle import nn - - class LinearNet(nn.Layer): - def __init__(self): - super(LinearNet, self).__init__() - self._linear = nn.Linear(224, 10) - - def forward(self, x): - return self._linear(x) - - inps = paddle.randn([1, 224], dtype='float32') - layer = LinearNet() - layer.eval() - path = "example/layer.pdmodel" - paddle.save(layer,path) - layer_load=paddle.load(path) .. code-block:: python - # example 4: static graph + # example 3: static graph import paddle import paddle.static as static @@ -126,7 +106,7 @@ Object,一个可以在paddle中使用的对象实例 .. code-block:: python - # example 5: load program + # example 4: load program import paddle paddle.enable_static() diff --git a/doc/paddle/api/paddle/framework/io/save_cn.rst b/doc/paddle/api/paddle/framework/io/save_cn.rst index 39e1ff19313..82bebe39e66 100644 --- a/doc/paddle/api/paddle/framework/io/save_cn.rst +++ b/doc/paddle/api/paddle/framework/io/save_cn.rst @@ -76,28 +76,7 @@ save .. code-block:: python - # example 3: Save layer - import paddle - from paddle import nn - - class LinearNet(nn.Layer): - def __init__(self): - super(LinearNet, self).__init__() - self._linear = nn.Linear(224, 10) - - def forward(self, x): - return self._linear(x) - - inps = paddle.randn([1, 224], dtype='float32') - layer = LinearNet() - layer.eval() - path = "example/layer.pdmodel" - paddle.save(layer,path) - - -.. code-block:: python - - # example 4: static graph + # example 3: static graph import paddle import paddle.static as static @@ -127,7 +106,7 @@ save .. code-block:: python - # example 5: save program + # example 4: save program import paddle paddle.enable_static() From 0821ad4a51c6b56b58a7cf7aa8b5413568bd41dc Mon Sep 17 00:00:00 2001 From: WeiXin Date: Fri, 14 May 2021 06:40:50 +0000 Subject: [PATCH 11/18] polish doc --- doc/paddle/api/paddle/framework/io/load_cn.rst | 2 +- doc/paddle/api/paddle/framework/io/save_cn.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/paddle/api/paddle/framework/io/load_cn.rst b/doc/paddle/api/paddle/framework/io/load_cn.rst index a5949e07e05..e1390c17a41 100644 --- a/doc/paddle/api/paddle/framework/io/load_cn.rst +++ b/doc/paddle/api/paddle/framework/io/load_cn.rst @@ -21,7 +21,7 @@ load 参数 ::::::::: - path (str) – 载入目标对象实例的路径。通常该路径是目标文件的路径,当从用于存储预测模型API的存储结果中载入state_dict时,该路径可能是一个文件前缀或者目录。 - - **config (dict, 可选) - 其他用于兼容的载入配置选项。这些选项将来可能被移除,如果不是必须使用,不推荐使用这些配置选项。默认为 ``None``。目前支持以下配置选项:(1) model_filename (str) - paddle 1.x版本 ``save_inference_model`` 接口存储格式的预测模型文件名,原默认文件名为 ``__model__`` ; (2) params_filename (str) - paddle 1.x版本 ``save_inference_model`` 接口存储格式的参数文件名,没有默认文件名,默认将各个参数分散存储为单独的文件; (3) return_numpy(bool) - 如果被指定为``True``,``load``的结果中的Tensor会被转化为``numpy.ndarray``,默认为``False``。 + - **config (dict, 可选) - 其他用于兼容的载入配置选项。这些选项将来可能被移除,如果不是必须使用,不推荐使用这些配置选项。默认为 ``None``。目前支持以下配置选项:(1) model_filename (str) - paddle 1.x版本 ``save_inference_model`` 接口存储格式的预测模型文件名,原默认文件名为 ``__model__`` ; (2) params_filename (str) - paddle 1.x版本 ``save_inference_model`` 接口存储格式的参数文件名,没有默认文件名,默认将各个参数分散存储为单独的文件; (3) return_numpy(bool) - 如果被指定为 ``True`` ,``load`` 的结果中的Tensor会被转化为 ``numpy.ndarray`` ,默认为 ``False`` 。 返回 ::::::::: diff --git a/doc/paddle/api/paddle/framework/io/save_cn.rst b/doc/paddle/api/paddle/framework/io/save_cn.rst index 82bebe39e66..38283022eac 100644 --- a/doc/paddle/api/paddle/framework/io/save_cn.rst +++ b/doc/paddle/api/paddle/framework/io/save_cn.rst @@ -29,7 +29,7 @@ save - **obj** (Object) – 要保存的对象实例。 - **path** (str) – 保存对象实例的路径。如果存储到当前路径,输入的path字符串将会作为保存的文件名。 - **protocol** (int, 可选) – pickle模块的协议版本,默认值为2,取值范围是[2,4]。 - - **configs** (dict, 可选) – 其他配置选项,目前支持以下选项:(1)use_binary_format(bool)- 如果被保存的对象是静态图的Tensor,你可以指定这个参数。如果被指定为``True``,这个Tensor会被保存为由paddle定义的二进制格式的文件;否则这个Tensor被保存为pickle格式。默认为``False``。 + - **configs** (dict, 可选) – 其他配置选项,目前支持以下选项:(1)use_binary_format(bool)- 如果被保存的对象是静态图的Tensor,你可以指定这个参数。如果被指定为 ``True`` ,这个Tensor会被保存为由paddle定义的二进制格式的文件;否则这个Tensor被保存为pickle格式。默认为 ``False`` 。 返回 ::::::::: From 669e77b7cfa2f23b2b03e5e381a448f3a62c2db4 Mon Sep 17 00:00:00 2001 From: WeiXin Date: Fri, 14 May 2021 06:53:40 +0000 Subject: [PATCH 12/18] polish code --- doc/paddle/api/paddle/framework/io/load_cn.rst | 1 + doc/paddle/api/paddle/framework/io/save_cn.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/doc/paddle/api/paddle/framework/io/load_cn.rst b/doc/paddle/api/paddle/framework/io/load_cn.rst index e1390c17a41..ae8855f1a9d 100644 --- a/doc/paddle/api/paddle/framework/io/load_cn.rst +++ b/doc/paddle/api/paddle/framework/io/load_cn.rst @@ -62,6 +62,7 @@ Object,一个可以在paddle中使用的对象实例 .. code-block:: python # example 2: Load multiple state_dict at the same time + import paddle from paddle import nn from paddle.optimizer import Adam diff --git a/doc/paddle/api/paddle/framework/io/save_cn.rst b/doc/paddle/api/paddle/framework/io/save_cn.rst index 38283022eac..639f2d4769f 100644 --- a/doc/paddle/api/paddle/framework/io/save_cn.rst +++ b/doc/paddle/api/paddle/framework/io/save_cn.rst @@ -64,6 +64,7 @@ save .. code-block:: python # example 2: Save multiple state_dict at the same time + import paddle from paddle import nn from paddle.optimizer import Adam From 5c33d96a49813a4b6eacd9f93b31502858980418 Mon Sep 17 00:00:00 2001 From: WeiXin Date: Fri, 14 May 2021 07:02:12 +0000 Subject: [PATCH 13/18] polish code --- doc/paddle/api/paddle/fluid/io/save_cn.rst | 4 ++-- doc/paddle/api/paddle/framework/io/save_cn.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/paddle/api/paddle/fluid/io/save_cn.rst b/doc/paddle/api/paddle/fluid/io/save_cn.rst index ef8c5691563..5b18a924c98 100644 --- a/doc/paddle/api/paddle/fluid/io/save_cn.rst +++ b/doc/paddle/api/paddle/fluid/io/save_cn.rst @@ -3,7 +3,7 @@ save ------------------------------- -.. py:function:: paddle.static.save(program, model_path, pickle_protocol=2) +.. py:function:: paddle.static.save(program, model_path, protocol=2) :api_attr: 声明式编程模式(静态图) @@ -19,7 +19,7 @@ save 参数: - **program** ( :ref:`cn_api_fluid_Program` ) – 要保存的Program。 - **model_path** (str) – 保存program的文件前缀。格式为 ``目录名称/文件前缀``。如果文件前缀为空字符串,会引发异常。 - - **pickle_protocol** (int, 可选) – pickle模块的协议版本,默认值为2,取值范围是[2,4]。 + - **protocol** (int, 可选) – pickle模块的协议版本,默认值为2,取值范围是[2,4]。在Python3环境中,推荐使用 ``protocol=4``。 返回: 无 diff --git a/doc/paddle/api/paddle/framework/io/save_cn.rst b/doc/paddle/api/paddle/framework/io/save_cn.rst index 639f2d4769f..7b3bc35de57 100644 --- a/doc/paddle/api/paddle/framework/io/save_cn.rst +++ b/doc/paddle/api/paddle/framework/io/save_cn.rst @@ -28,7 +28,7 @@ save ::::::::: - **obj** (Object) – 要保存的对象实例。 - **path** (str) – 保存对象实例的路径。如果存储到当前路径,输入的path字符串将会作为保存的文件名。 - - **protocol** (int, 可选) – pickle模块的协议版本,默认值为2,取值范围是[2,4]。 + - **protocol** (int, 可选) – pickle模块的协议版本,默认值为2,取值范围是[2,4]。在Python3环境中,推荐使用 ``protocol=4``。 - **configs** (dict, 可选) – 其他配置选项,目前支持以下选项:(1)use_binary_format(bool)- 如果被保存的对象是静态图的Tensor,你可以指定这个参数。如果被指定为 ``True`` ,这个Tensor会被保存为由paddle定义的二进制格式的文件;否则这个Tensor被保存为pickle格式。默认为 ``False`` 。 返回 From 1935249206557ce532321e8fac3ba7d3d3cf3ba8 Mon Sep 17 00:00:00 2001 From: WeiXin Date: Fri, 14 May 2021 07:35:04 +0000 Subject: [PATCH 14/18] polish doc --- doc/paddle/faq/save_cn.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/paddle/faq/save_cn.md b/doc/paddle/faq/save_cn.md index 563e6c82df6..67f75df71d0 100644 --- a/doc/paddle/faq/save_cn.md +++ b/doc/paddle/faq/save_cn.md @@ -49,16 +49,16 @@ adam.set_state_dict(opti_state_dict) ##### 问题:paddle.load可以加载哪些API产生的模型? + 答复: - 为了更高效地使用paddle存储的模型参数, ``paddle.load`` 支持从除 ``paddle.save`` 之外的其他save相关API的存储结果中载入 ``state_dict`` ,但是在不同场景中,参数 ``path`` 的形式有所不同: + 为了更高效地使用paddle存储的模型参数,`paddle.load`支持从除`paddle.save`之外的其他save相关API的存储结果中载入`state_dict`,但是在不同场景中,参数`path`的形式有所不同: - 1. 从 ``paddle.static.save`` 或者 ``paddle.Model().save(training=True)`` 的保存结果载入: ``path`` 需要是完整的文件名,例如 ``model.pdparams`` 或者 ``model.opt`` ; + 1. 从`paddle.static.save`或者`paddle.Model().save(training=True)`的保存结果载入:`path`需要是完整的文件名,例如`model.pdparams`或者`model.opt`; - 2. 从 ``paddle.jit.save`` 或者 ``paddle.static.save_inference_model`` 或者 ``paddle.Model().save(training=False)`` 的保存结果载入: ``path`` 需要是路径前缀, 例如 ``model/mnist`` , ``paddle.load`` 会从 ``mnist.pdmodel`` 和 ``mnist.pdiparams`` 中解析 ``state_dict`` 的信息并返回。 + 2. 从`paddle.jit.save`或者`paddle.static.save_inference_model`或者`paddle.Model().save(training=False)`的保存结果载入:`path`需要是路径前缀, 例如`model/mnist`,`paddle.load`会从`mnist.pdmodel`和`mnist.pdiparams`中解析`state_dict`的信息并返回。 - 3. 从paddle 1.x API ``paddle.fluid.io.save_inference_model`` 或者 ``paddle.fluid.io.save_params/save_persistables`` 的保存结果载入: ``path`` 需要是目录,例如 ``model`` ,此处model是一个文件夹路径。 + 3. 从paddle 1.x API`paddle.fluid.io.save_inference_model`或者`paddle.fluid.io.save_params/save_persistables`的保存结果载入:`path`需要是目录,例如`model`,此处model是一个文件夹路径。 - 需要注意的是,如果从 ``paddle.static.save`` 或者 ``paddle.static.save_inference_model`` 等静态图API的存储结果中载入 ``state_dict`` ,动态图模式下参数的结构性变量名将无法被恢复。在将载入的 ``state_dict`` 配置到当前Layer中时,需要配置 ``Layer.set_state_dict`` 的参数 ``use_structured_name=False`` 。 + 需要注意的是,如果从`paddle.static.save`或者`paddle.static.save_inference_model`等静态图API的存储结果中载入`state_dict`,动态图模式下参数的结构性变量名将无法被恢复。在将载入的`state_dict`配置到当前Layer中时,需要配置`Layer.set_state_dict`的参数`use_structured_name=False`。 ##### 问题:paddle.save 是如何保存state_dict,Layer对象,Tensor以及包含Tensor的嵌套list、tuple、dict的呢? + 答复: From b03a054e2c9c889991cc15a4ec7fed5a1701d77e Mon Sep 17 00:00:00 2001 From: WeiXin Date: Fri, 14 May 2021 07:48:15 +0000 Subject: [PATCH 15/18] polish code --- doc/paddle/faq/save_cn.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/doc/paddle/faq/save_cn.md b/doc/paddle/faq/save_cn.md index 67f75df71d0..6effbda1d25 100644 --- a/doc/paddle/faq/save_cn.md +++ b/doc/paddle/faq/save_cn.md @@ -49,16 +49,13 @@ adam.set_state_dict(opti_state_dict) ##### 问题:paddle.load可以加载哪些API产生的模型? + 答复: - 为了更高效地使用paddle存储的模型参数,`paddle.load`支持从除`paddle.save`之外的其他save相关API的存储结果中载入`state_dict`,但是在不同场景中,参数`path`的形式有所不同: + 为了更高效地使用paddle存储的模型参数,`paddle.load`支持从除`paddle.save`之外的其他save相关API的存储结果中载入`state_dict`,但是在不同场景中,参数`path`的形式有所不同: + 1. 从`paddle.static.save`或者`paddle.Model().save(training=True)`的保存结果载入:`path`需要是完整的文件名,例如`model.pdparams`或者`model.opt`; + 2. 从`paddle.jit.save`或者`paddle.static.save_inference_model`或者`paddle.Model().save(training=False)`的保存结果载入:`path`需要是路径前缀, 例如`model/mnist`,`paddle.load`会从`mnist.pdmodel`和`mnist.pdiparams`中解析`state_dict`的信息并返回。 + 3. 从paddle 1.x API`paddle.fluid.io.save_inference_model`或者`paddle.fluid.io.save_params/save_persistables`的保存结果载入:`path`需要是目录,例如`model`,此处model是一个文件夹路径。 - 1. 从`paddle.static.save`或者`paddle.Model().save(training=True)`的保存结果载入:`path`需要是完整的文件名,例如`model.pdparams`或者`model.opt`; - 2. 从`paddle.jit.save`或者`paddle.static.save_inference_model`或者`paddle.Model().save(training=False)`的保存结果载入:`path`需要是路径前缀, 例如`model/mnist`,`paddle.load`会从`mnist.pdmodel`和`mnist.pdiparams`中解析`state_dict`的信息并返回。 - - 3. 从paddle 1.x API`paddle.fluid.io.save_inference_model`或者`paddle.fluid.io.save_params/save_persistables`的保存结果载入:`path`需要是目录,例如`model`,此处model是一个文件夹路径。 - - - 需要注意的是,如果从`paddle.static.save`或者`paddle.static.save_inference_model`等静态图API的存储结果中载入`state_dict`,动态图模式下参数的结构性变量名将无法被恢复。在将载入的`state_dict`配置到当前Layer中时,需要配置`Layer.set_state_dict`的参数`use_structured_name=False`。 + 需要注意的是,如果从`paddle.static.save`或者`paddle.static.save_inference_model`等静态图API的存储结果中载入`state_dict`,动态图模式下参数的结构性变量名将无法被恢复。在将载入的`state_dict`配置到当前Layer中时,需要配置`Layer.set_state_dict`的参数`use_structured_name=False`。 ##### 问题:paddle.save 是如何保存state_dict,Layer对象,Tensor以及包含Tensor的嵌套list、tuple、dict的呢? + 答复: From 3d86759e08002d3edd4c4185fe9ecd6965fb55ca Mon Sep 17 00:00:00 2001 From: WeiXin Date: Fri, 14 May 2021 07:58:59 +0000 Subject: [PATCH 16/18] polish doc --- doc/paddle/api/paddle/framework/io/load_cn.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/paddle/api/paddle/framework/io/load_cn.rst b/doc/paddle/api/paddle/framework/io/load_cn.rst index ae8855f1a9d..3210eead920 100644 --- a/doc/paddle/api/paddle/framework/io/load_cn.rst +++ b/doc/paddle/api/paddle/framework/io/load_cn.rst @@ -11,7 +11,7 @@ load 目前支持载入:Layer 或者 Optimizer 的 ``state_dict``,Layer对象,Tensor以及包含Tensor的嵌套list、tuple、dict,Program。 -如果想进一步了解这个API,请参考: +遇到使用问题,请参考: .. toctree:: :maxdepth: 1 From 3e5857d642141892abb83d34cfb27fdb97ddc46b Mon Sep 17 00:00:00 2001 From: WeiXin Date: Fri, 14 May 2021 08:32:05 +0000 Subject: [PATCH 17/18] polish code according to comment --- doc/paddle/api/paddle/fluid/framework/Program_cn.rst | 2 +- doc/paddle/faq/save_cn.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/paddle/api/paddle/fluid/framework/Program_cn.rst b/doc/paddle/api/paddle/fluid/framework/Program_cn.rst index 80340011bd4..4b9debe4456 100644 --- a/doc/paddle/api/paddle/fluid/framework/Program_cn.rst +++ b/doc/paddle/api/paddle/fluid/framework/Program_cn.rst @@ -472,7 +472,7 @@ list[ :ref:`api_guide_parameter` ],一个包含当前Program中所有参数的 .. py:method:: state_dict(mode='all', scope=None) -获取当前 ``Program`` 持久性变量。并将所有持久性变量s存放在dict结构中。 +获取当前 ``Program`` 持久性变量。并将所有持久性变量存放在dict结构中。 参数 ::::::::: diff --git a/doc/paddle/faq/save_cn.md b/doc/paddle/faq/save_cn.md index 6effbda1d25..f54c7cb67f8 100644 --- a/doc/paddle/faq/save_cn.md +++ b/doc/paddle/faq/save_cn.md @@ -46,7 +46,7 @@ emb.set_state_dict(para_state_dict) adam.set_state_dict(opti_state_dict) ``` -##### 问题:paddle.load可以加载哪些API产生的模型? +##### 问题:paddle.load可以加载哪些API产生的结果呢? + 答复: 为了更高效地使用paddle存储的模型参数,`paddle.load`支持从除`paddle.save`之外的其他save相关API的存储结果中载入`state_dict`,但是在不同场景中,参数`path`的形式有所不同: From 42dd21ae61dcbe2a77bb0588555a257a1635d48d Mon Sep 17 00:00:00 2001 From: WeiXin Date: Fri, 14 May 2021 08:43:00 +0000 Subject: [PATCH 18/18] polish code --- doc/paddle/api/paddle/fluid/framework/Program_cn.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/paddle/api/paddle/fluid/framework/Program_cn.rst b/doc/paddle/api/paddle/fluid/framework/Program_cn.rst index 4b9debe4456..e24ebf87404 100644 --- a/doc/paddle/api/paddle/fluid/framework/Program_cn.rst +++ b/doc/paddle/api/paddle/fluid/framework/Program_cn.rst @@ -512,7 +512,7 @@ dict, 包含持久性变量的dict,键值是持久性变量的名字,值 参数 ::::::::: - state_dict (dict) - 包含持久性变量的字典。键值是持久性变量的名字,值为持久性变量。 - - scope (Scope, 可选) - 如果scope为 ``None`` ,通过 `paddle.static.global_scope()` 获取全局/默认作用域实例,并将 ``state_dict`` 中参数和可持久性buffers设置到这个作用域中;否则将 ``state_dict`` 设置到指定的 ``scope`` 中。默认值为 ``None`` 。 + - scope (Scope, 可选) - 如果scope为 ``None`` ,通过 `paddle.static.global_scope()` 获取全局/默认作用域实例,并将 ``state_dict`` 中久性变量设置到这个作用域中;否则将 ``state_dict`` 设置到指定的 ``scope`` 中。默认值为 ``None`` 。 返回 :::::::::