diff --git a/ci_scripts/api_white_list.txt b/ci_scripts/api_white_list.txt index 4c6a6bf113739606de13be095546ad38eb18714c..cb9076389f836aa125b0cee331ece46e5653eddd 100644 --- a/ci_scripts/api_white_list.txt +++ b/ci_scripts/api_white_list.txt @@ -7,3 +7,13 @@ paddle/optimizer/Dpsgd_cn.rst paddle/reader/ComposeNotAligned_cn.rst paddle/fluid/layers/scatter_cn.rst paddle/tensor/manipulation/scatter_cn.rst +paddle/distributed/fleet/Fleet_cn.rst +paddle/distributed/fleet/utils/fs/ExecuteError_cn.rst +paddle/distributed/fleet/utils/fs/FSFileExistsError_cn.rst +paddle/distributed/fleet/utils/fs/FSFileNotExistsError_cn.rst +paddle/distributed/fleet/utils/fs/FSShellCmdAborted_cn.rst +paddle/distributed/fleet/utils/fs/FSTimeOut_cn.rst +paddle/distributed/fleet/utils/fs/FS_cn.rst +paddle/distributed/fleet/utils/fs/HDFSClient_cn.rst +paddle/distributed/fleet/utils/fs/LocalFS_cn.rst +upgrade_guide_cn.md diff --git a/ci_scripts/check_api_cn.sh b/ci_scripts/check_api_cn.sh index c2cd521f9376d5e2bc0a255b6a8d47bf183a5ad6..a8a565a931b5a5a131cf2fab385dc6d6c3b6fdf9 100644 --- a/ci_scripts/check_api_cn.sh +++ b/ci_scripts/check_api_cn.sh @@ -1,22 +1,72 @@ #!/bin/bash +set -x -git_files=`git diff --numstat upstream/$BRANCH | awk '{print $NF}'` +function build_paddle() { + git clone https://github.com/PaddlePaddle/Paddle.git + mkdir Paddle/build + cd Paddle/build -for file in `echo $git_files`;do - grep "code-block" ../$file - if [ $? -eq 0 ] ;then - echo $file | grep "doc/paddle/api/paddle/.*_cn.rst" - if [ $? -eq 0 ];then - api_file=`echo $file | sed 's#doc/paddle/api/##g'` - grep -w "${api_file}" ${DIR_PATH}/api_white_list.txt - if [ $? -ne 0 ];then + cmake .. -DWITH_GPU=ON -DWITH_COVERAGE=OFF -DWITH_TESTING=OFF -DCMAKE_BUILD_TYPE=Release + make -j`nproc` + pip install -U python/dist/paddlepaddle_gpu-0.0.0-cp27-cp27mu-linux_x86_64.whl + + cd - +} + +need_check_files="" +function find_need_check_files() { + git_files=`git diff --numstat upstream/$BRANCH | awk '{print $NF}'` + + for file in `echo $git_files`;do + grep "code-block" ../$file + if [ $? -eq 0 ] ;then + echo $file | grep "doc/paddle/api/paddle/.*_cn.rst" + if [ $? -eq 0 ];then + api_file=`echo $file | sed 's#doc/paddle/api/##g'` + grep -w "${api_file}" ${DIR_PATH}/api_white_list.txt + if [ $? -ne 0 ];then + need_check_files="${need_check_files} $file" + fi + fi + fi + done +} + + +need_check_cn_doc_files=`git diff --numstat upstream/$BRANCH | awk '{print $NF}' | grep "doc/paddle/api/paddle/.*_cn.rst" | sed 's#doc/##g'` +echo $need_check_cn_doc_files +find_need_check_files +if [ "$need_check_files" = "" -a "$need_check_cn_doc_files" = "" ] +then + echo "need check files is empty, skip chinese api check" +else + echo "need check files is not empty, begin to build and install paddle" + build_paddle + if [ $? -ne 0 ];then + echo "paddle build error" + exit 5 + fi + + if [ "${need_check_files}" != "" ]; then + for file in $need_check_files;do python chinese_samplecode_processor.py ../$file if [ $? -ne 0 ];then - echo "chinese sample code failed" + echo "chinese sample code failed, the file is ${file}" exit 5 fi - fi + done fi - fi -done + if [ "${need_check_cn_doc_files}" != "" ];then + cd ../doc/paddle/api + python gen_doc.py + cd - + + for file in $need_check_cn_doc_files; do + cat ../doc/paddle/api/en_cn_files_diff | awk '{print $1}' | grep ${file} + if [ $? -eq 0 ];then + echo "Chinese doc file exist, but the Englist doc does not exist, the Chinese file is ${file}" + fi + done + fi +fi diff --git a/ci_scripts/checkapproval.sh b/ci_scripts/checkapproval.sh index 9bd4b99296598c78df81ec65d533fe8cab4ecdc4..27a3aa5ae4402fe013dcbec352d6dc7a4457bbd0 100644 --- a/ci_scripts/checkapproval.sh +++ b/ci_scripts/checkapproval.sh @@ -1,5 +1,7 @@ #!/bin/bash +set -x + API_FILES=("doc/paddle/api/paddle") for API_FILE in ${API_FILES[*]}; do diff --git a/doc/fluid/advanced_guide/dygraph_to_static/program_translator_cn.rst b/doc/fluid/advanced_guide/dygraph_to_static/program_translator_cn.rst index 03852fc58a6bbe9c515de9138c40d38e837d25a8..208fab9d19ae4654e76df7d1ea8666b20dc874e1 100644 --- a/doc/fluid/advanced_guide/dygraph_to_static/program_translator_cn.rst +++ b/doc/fluid/advanced_guide/dygraph_to_static/program_translator_cn.rst @@ -60,7 +60,7 @@ trace是指在模型运行时记录下其运行过哪些算子。TracedLayer就 place = paddle.CPUPlace() exe = paddle.Executor(place) - program, feed_vars, fetch_vars = paddle.io.load_inference_model(save_dirname, exe) + program, feed_vars, fetch_vars = paddle.static.load_inference_model(save_dirname, exe) fetch, = exe.run(program, feed={feed_vars[0]: in_np}, fetch_list=fetch_vars) diff --git a/doc/fluid/advanced_guide/dygraph_to_static/program_translator_en.rst b/doc/fluid/advanced_guide/dygraph_to_static/program_translator_en.rst index 573ddbb79893acb9386c87bec373035a439037b4..60a204729578a8570a5d73b55d6b37b3f931c0f2 100644 --- a/doc/fluid/advanced_guide/dygraph_to_static/program_translator_en.rst +++ b/doc/fluid/advanced_guide/dygraph_to_static/program_translator_en.rst @@ -60,7 +60,7 @@ Load model and run it in static graph mode: place = paddle.CPUPlace() exe = paddle.Executor(place) - program, feed_vars, fetch_vars = paddle.io.load_inference_model(save_dirname, exe) + program, feed_vars, fetch_vars = paddle.static.load_inference_model(save_dirname, exe) fetch, = exe.run(program, feed={feed_vars[0]: in_np}, fetch_list=fetch_vars) However, as tracing only records operators once, if user's code contains Tensor-dependent (including Tensor value or Tensor shape) control flow, that is the Tensor can cause different operators being executed, then TracedLayer cannot handle this case. For instance: diff --git a/doc/fluid/api/data/dataset.rst b/doc/fluid/api/data/dataset.rst index 52d7c44ac948b54c167c58d57a580ccd32c95d48..420a5fc75d8e3bb403fcf9f705dd80efc24044aa 100644 --- a/doc/fluid/api/data/dataset.rst +++ b/doc/fluid/api/data/dataset.rst @@ -10,7 +10,6 @@ dataset dataset/imdb.rst dataset/imikolov.rst dataset/movielens.rst - dataset/sentiment.rst dataset/uci_housing.rst dataset/wmt14.rst dataset/wmt16.rst diff --git a/doc/fluid/api/data/dataset/sentiment.rst b/doc/fluid/api/data/dataset/sentiment.rst deleted file mode 100644 index 6713c9ef983a31d4c495ed87394f383d0080b529..0000000000000000000000000000000000000000 --- a/doc/fluid/api/data/dataset/sentiment.rst +++ /dev/null @@ -1,6 +0,0 @@ -sentiment -+++++++++ - -.. automodule:: paddle.dataset.sentiment - :members: - :noindex: diff --git a/doc/fluid/api/io.rst b/doc/fluid/api/io.rst index 666d584ca533027ddeb3f1a16575365804260b81..eb220fe7e911f59bb10869b4a93fcb59d34d475e 100644 --- a/doc/fluid/api/io.rst +++ b/doc/fluid/api/io.rst @@ -1,5 +1,5 @@ ======== -paddle.io +fluid.io ======== .. toctree:: @@ -7,14 +7,10 @@ paddle.io io/batch.rst io/BatchSampler.rst - io/buffered.rst - io/cache.rst - io/chain.rst - io/compose.rst io/ComposeNotAligned.rst io/DataLoader.rst io/Dataset.rst - io/firstn.rst + io/default_collate_fn.rst io/get_program_parameter.rst io/get_program_persistable_vars.rst io/load.rst @@ -23,17 +19,10 @@ paddle.io io/load_persistables.rst io/load_program_state.rst io/load_vars.rst - io/map_readers.rst - io/multiprocess_reader.rst io/PyReader.rst io/save.rst io/save_inference_model.rst - io/save_inference_model.rst io/save_params.rst io/save_persistables.rst io/save_vars.rst io/set_program_state.rst - io/set_program_state.rst - io/shuffle.rst - io/shuffle.rst - io/xmap_readers.rst diff --git a/doc/fluid/api/io/buffered.rst b/doc/fluid/api/io/buffered.rst deleted file mode 100644 index 125e100dd8eaac9e09b40bf04d31756b6cade33a..0000000000000000000000000000000000000000 --- a/doc/fluid/api/io/buffered.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. THIS FILE IS GENERATED BY `gen_doc.{py|sh}` - !DO NOT EDIT THIS FILE MANUALLY! - -.. _api_fluid_io_buffered: - -buffered --------- - -.. autofunction:: paddle.fluid.io.buffered - :noindex: - diff --git a/doc/fluid/api/io/cache.rst b/doc/fluid/api/io/cache.rst deleted file mode 100644 index 6da87c92eb7730d26d45795094688044f490974d..0000000000000000000000000000000000000000 --- a/doc/fluid/api/io/cache.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. THIS FILE IS GENERATED BY `gen_doc.{py|sh}` - !DO NOT EDIT THIS FILE MANUALLY! - -.. _api_fluid_io_cache: - -cache ------ - -.. autofunction:: paddle.fluid.io.cache - :noindex: - diff --git a/doc/fluid/api/io/chain.rst b/doc/fluid/api/io/chain.rst deleted file mode 100644 index efc904b654206f8e107af46df852fafd4472f8c4..0000000000000000000000000000000000000000 --- a/doc/fluid/api/io/chain.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. THIS FILE IS GENERATED BY `gen_doc.{py|sh}` - !DO NOT EDIT THIS FILE MANUALLY! - -.. _api_fluid_io_chain: - -chain ------ - -.. autofunction:: paddle.fluid.io.chain - :noindex: - diff --git a/doc/fluid/api/io/compose.rst b/doc/fluid/api/io/compose.rst deleted file mode 100644 index bac5affe50192ec8fb33c6294f1012d883f8ef15..0000000000000000000000000000000000000000 --- a/doc/fluid/api/io/compose.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. THIS FILE IS GENERATED BY `gen_doc.{py|sh}` - !DO NOT EDIT THIS FILE MANUALLY! - -.. _api_fluid_io_compose: - -compose -------- - -.. autofunction:: paddle.fluid.io.compose - :noindex: - diff --git a/doc/fluid/api/io/default_collate_fn.rst b/doc/fluid/api/io/default_collate_fn.rst new file mode 100644 index 0000000000000000000000000000000000000000..38f34e1eeaa476fb77874ea015dbfd4213a5f9fe --- /dev/null +++ b/doc/fluid/api/io/default_collate_fn.rst @@ -0,0 +1,11 @@ +.. THIS FILE IS GENERATED BY `gen_doc.{py|sh}` + !DO NOT EDIT THIS FILE MANUALLY! + +.. _api_fluid_io_default_collate_fn: + +default_collate_fn +------------------ + +.. autofunction:: paddle.fluid.io.default_collate_fn + :noindex: + diff --git a/doc/fluid/api/io/firstn.rst b/doc/fluid/api/io/firstn.rst deleted file mode 100644 index 512dab717dbba79401450af06f551d4ae0224011..0000000000000000000000000000000000000000 --- a/doc/fluid/api/io/firstn.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. THIS FILE IS GENERATED BY `gen_doc.{py|sh}` - !DO NOT EDIT THIS FILE MANUALLY! - -.. _api_fluid_io_firstn: - -firstn ------- - -.. autofunction:: paddle.fluid.io.firstn - :noindex: - diff --git a/doc/fluid/api/io/map_readers.rst b/doc/fluid/api/io/map_readers.rst deleted file mode 100644 index 5e7558baf1efe603a3415e789439a24d9e8c36bc..0000000000000000000000000000000000000000 --- a/doc/fluid/api/io/map_readers.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. THIS FILE IS GENERATED BY `gen_doc.{py|sh}` - !DO NOT EDIT THIS FILE MANUALLY! - -.. _api_fluid_io_map_readers: - -map_readers ------------ - -.. autofunction:: paddle.fluid.io.map_readers - :noindex: - diff --git a/doc/fluid/api/io/multiprocess_reader.rst b/doc/fluid/api/io/multiprocess_reader.rst deleted file mode 100644 index 24b2a3bd564a114431ffe5e48e73372528b1b443..0000000000000000000000000000000000000000 --- a/doc/fluid/api/io/multiprocess_reader.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. THIS FILE IS GENERATED BY `gen_doc.{py|sh}` - !DO NOT EDIT THIS FILE MANUALLY! - -.. _api_fluid_io_multiprocess_reader: - -multiprocess_reader -------------------- - -.. autofunction:: paddle.fluid.io.multiprocess_reader - :noindex: - diff --git a/doc/fluid/api/io/shuffle.rst b/doc/fluid/api/io/shuffle.rst deleted file mode 100644 index dccf6d5c6b53bf4234a23f37952e341eb9390282..0000000000000000000000000000000000000000 --- a/doc/fluid/api/io/shuffle.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. THIS FILE IS GENERATED BY `gen_doc.{py|sh}` - !DO NOT EDIT THIS FILE MANUALLY! - -.. _api_fluid_io_shuffle: - -shuffle -------- - -.. autofunction:: paddle.fluid.io.shuffle - :noindex: - diff --git a/doc/fluid/api/io/xmap_readers.rst b/doc/fluid/api/io/xmap_readers.rst deleted file mode 100644 index 77b3e78993974c4dd7905c052928307ddc7a6baa..0000000000000000000000000000000000000000 --- a/doc/fluid/api/io/xmap_readers.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. THIS FILE IS GENERATED BY `gen_doc.{py|sh}` - !DO NOT EDIT THIS FILE MANUALLY! - -.. _api_fluid_io_xmap_readers: - -xmap_readers ------------- - -.. autofunction:: paddle.fluid.io.xmap_readers - :noindex: - diff --git a/doc/fluid/api_cn/data/dataset_cn.rst b/doc/fluid/api_cn/data/dataset_cn.rst index 87017bd66993881d0cfba8c93bdaf92d31592512..17a6a32b855cdcc4f52a77e4639d6a8c8a87eeb4 100644 --- a/doc/fluid/api_cn/data/dataset_cn.rst +++ b/doc/fluid/api_cn/data/dataset_cn.rst @@ -14,7 +14,6 @@ dataset dataset_cn/imdb_cn.rst dataset_cn/imikolov_cn.rst dataset_cn/movielens_cn.rst - dataset_cn/sentiment_cn.rst dataset_cn/uci_housing_cn.rst dataset_cn/wmt14_cn.rst dataset_cn/wmt16_cn.rst diff --git a/doc/fluid/api_cn/data/dataset_cn/sentiment_cn.rst b/doc/fluid/api_cn/data/dataset_cn/sentiment_cn.rst deleted file mode 100644 index d5826830f07689805114028f6b387731e4770be2..0000000000000000000000000000000000000000 --- a/doc/fluid/api_cn/data/dataset_cn/sentiment_cn.rst +++ /dev/null @@ -1,28 +0,0 @@ -.. _cn_api_paddle_dataset_sentiment: - -sentiment -------------------------------- - -脚本获取并预处理由NLTK提供的movie_reviews数据集。 - - -.. py:function:: paddle.dataset.sentiment.get_word_dict() - -按照样本中出现的单词的频率对单词进行排序。 - -返回: words_freq_sorted - -.. py:function:: paddle.dataset.sentiment.train() - -默认的训练集reader creator。 - -.. py:function:: paddle.dataset.sentiment.test() - -默认的测试集reader creator。 - -.. py:function:: paddle.dataset.sentiment.convert(path) - -将数据集转换为recordio格式。 - - - diff --git a/doc/fluid/api_cn/fluid_cn/save_cn.rst b/doc/fluid/api_cn/fluid_cn/save_cn.rst index a15b23f2b5b1b798943dcb6d7ef49ce8fac229f1..ab1f63e8caffa07401de80344872946c984be8d9 100644 --- a/doc/fluid/api_cn/fluid_cn/save_cn.rst +++ b/doc/fluid/api_cn/fluid_cn/save_cn.rst @@ -7,8 +7,8 @@ save .. py:function:: paddle.fluid.save(program, model_path) :api_attr: 声明式编程模式(静态图) -:alias_main: paddle.save -:alias: paddle.save,paddle.tensor.save,paddle.tensor.io.save +:alias_main: paddle.static.save +:alias: paddle.static.save :old_api: paddle.fluid.save diff --git a/doc/fluid/api_cn/io_cn/load_cn.rst b/doc/fluid/api_cn/io_cn/load_cn.rst index 863dd4ea083bd3d663e4e3a4b06eaed787086b2d..1a8e78f994ccd8d045b14ba059be9faf133e6309 100644 --- a/doc/fluid/api_cn/io_cn/load_cn.rst +++ b/doc/fluid/api_cn/io_cn/load_cn.rst @@ -6,8 +6,8 @@ load .. py:function:: paddle.fluid.io.load(program, model_path, executor=None, var_list=None) :api_attr: 声明式编程模式(静态图) -:alias_main: paddle.load -:alias: paddle.load,paddle.tensor.load,paddle.tensor.io.load +:alias_main: paddle.static.load +:alias: paddle.static.load :old_api: paddle.fluid.io.load diff --git a/doc/fluid/api_cn/layers_cn/add_position_encoding_cn.rst b/doc/fluid/api_cn/layers_cn/add_position_encoding_cn.rst index abba3377ba359ac496848262f1fe29705ea504b0..b6eda83b8449d53300b75f499d9eb38c9e3cc8d1 100644 --- a/doc/fluid/api_cn/layers_cn/add_position_encoding_cn.rst +++ b/doc/fluid/api_cn/layers_cn/add_position_encoding_cn.rst @@ -40,13 +40,13 @@ add_position_encoding .. code-block:: python - import paddle.fluid as fluid + import numpy as np + import paddle + import paddle.nn.functional as F - tensor = fluid.data( - name='tensor', - shape=[None, 64, 512], - dtype='float32') - position_tensor = fluid.layers.add_position_encoding( + tensor = np.random.randn(16, 32, 64) + tensor = paddle.to_tensor(tensor) + position_tensor = F.add_position_encoding( input=tensor, alpha=1.0, beta=1.0) diff --git a/doc/fluid/api_cn/layers_cn/warpctc_cn.rst b/doc/fluid/api_cn/layers_cn/warpctc_cn.rst index dbb4c4ca829330844170359127680fe870ac618c..5295e15864d610f7bf0daeb16f388bcdb2869ff9 100644 --- a/doc/fluid/api_cn/layers_cn/warpctc_cn.rst +++ b/doc/fluid/api_cn/layers_cn/warpctc_cn.rst @@ -14,7 +14,7 @@ warpctc 该OP用于计算 `CTC loss `_ 。该OP的底层调用了第三方 `baidu-research::warp-ctc `_ 的实现。 参数: - - **input** (Variable) - 可以是3-D Tensor或2-D LoDTensor。当输入类型是3-D Tensor时,则表示输入是经过padding的定长序列,其 shape 必须是 ``[seq_length, batch_size, num_classes + 1]`` 。当输入类型是2-D LoDTensor时,则表示输入为变长序列,其shape必须为 ``[Lp,num_classes+1]`` , ``Lp`` 是所有输入序列长度之和。以上 shape 中的 ``num_classes`` 是实际类别数,不包括空白标签。该输入不需要经过 softmax 操作,因为该OP的内部对 ``input`` 做了 softmax 操作。数据类型仅支持float32。 + - **input** (Variable) - 可以是3-D Tensor或2-D LoDTensor。当输入类型是3-D Tensor时,则表示输入是经过padding的定长序列,其 shape 必须是 ``[seq_length, batch_size, num_classes + 1]`` 。当输入类型是2-D LoDTensor时,则表示输入为变长序列,其shape必须为 ``[Lp,num_classes+1]`` , ``Lp`` 是所有输入序列长度之和。以上 shape 中的 ``num_classes`` 是实际类别数,不包括空白标签。该输入不需要经过 softmax 操作,因为该OP的内部对 ``input`` 做了 softmax 操作。数据类型支持 float32 和 float64。 - **label** (Variable) - 可以是3-D Tensor或2-D LoDTensor,需要跟 ``input`` 保持一致。当输入类型为3-D Tensor时,表示输入是经过 padding 的定长序列,其 shape 为 ``[batch_size, label_length]`` ,其中, ``label_length`` 是最长的 label 序列的长度。当输入类型是2-D LoDTensor时,则表示输入为变长序列,其shape必须为 ``[Lp, 1]`` , 其中 ``Lp`` 是所有 label 序列的长度和。 ``label`` 中的数值为字符ID。数据类型支持int32。 - **blank** (int,可选) - 空格标记的ID,其取值范围为 ``[0,num_classes+1)`` 。数据类型支持int32。缺省值为0。 - **norm_by_times** (bool,可选) - 是否根据序列长度对梯度进行正则化。数据类型支持 bool 。缺省值为False。 diff --git a/doc/fluid/api_cn/nn_cn/functional_cn/ctc_loss_cn.rst b/doc/fluid/api_cn/nn_cn/functional_cn/ctc_loss_cn.rst index 2722525a61feefc4ea1bb3263e7eec0f88462796..292b6d82f8101a5e0284c9d2bf616753adf39a49 100644 --- a/doc/fluid/api_cn/nn_cn/functional_cn/ctc_loss_cn.rst +++ b/doc/fluid/api_cn/nn_cn/functional_cn/ctc_loss_cn.rst @@ -8,7 +8,7 @@ ctc_loss 参数 ::::::::: - - **log_probs** (Tensor): - 经过 padding 的概率序列,其 shape 必须是 [max_logit_length, batch_size, num_classes + 1]。其中 max_logit_length 是最长输入序列的长度。该输入不需要经过 softmax 操作,因为该 OP 的内部对 input 做了 softmax 操作。数据类型仅支持float32。 + - **log_probs** (Tensor): - 经过 padding 的概率序列,其 shape 必须是 [max_logit_length, batch_size, num_classes + 1]。其中 max_logit_length 是最长输入序列的长度。该输入不需要经过 softmax 操作,因为该 OP 的内部对 input 做了 softmax 操作。数据类型支持 float32 和 float64。 - **labels** (Tensor): - 经过 padding 的标签序列,其 shape 为 [batch_size, max_label_length],其中 max_label_length 是最长的 label 序列的长度。数据类型支持int32。 - **input_lengths** (Tensor): - 表示输入 ``log_probs`` 数据中每个序列的长度,shape为 [batch_size] 。数据类型支持int64。 - **label_lengths** (Tensor): - 表示 label 中每个序列的长度,shape为 [batch_size] 。数据类型支持int64。 diff --git a/doc/fluid/api_cn/nn_cn/loss_cn/CTCLoss_cn.rst b/doc/fluid/api_cn/nn_cn/loss_cn/CTCLoss_cn.rst index a2ad0c28a4058d8cbdfc447b9f890e0ce9d24185..708f5797118779823630b38c5ac157c7ba0be5ca 100644 --- a/doc/fluid/api_cn/nn_cn/loss_cn/CTCLoss_cn.rst +++ b/doc/fluid/api_cn/nn_cn/loss_cn/CTCLoss_cn.rst @@ -13,7 +13,7 @@ CTCLoss 形状 ::::::::: - - **log_probs** (Tensor): - 经过 padding 的概率序列,其 shape 必须是 [max_logit_length, batch_size, num_classes + 1]。其中 max_logit_length 是最长输入序列的长度。该输入不需要经过 softmax 操作,因为该 OP 的内部对 input 做了 softmax 操作。数据类型仅支持float32。 + - **log_probs** (Tensor): - 经过 padding 的概率序列,其 shape 必须是 [max_logit_length, batch_size, num_classes + 1]。其中 max_logit_length 是最长输入序列的长度。该输入不需要经过 softmax 操作,因为该 OP 的内部对 input 做了 softmax 操作。数据类型支持 float32 和 float64。 - **labels** (Tensor): - 经过 padding 的标签序列,其 shape 为 [batch_size, max_label_length],其中 max_label_length 是最长的 label 序列的长度。数据类型支持int32。 - **input_lengths** (Tensor): - 表示输入 ``log_probs`` 数据中每个序列的长度,shape为 [batch_size] 。数据类型支持int64。 - **label_lengths** (Tensor): - 表示 label 中每个序列的长度,shape为 [batch_size] 。数据类型支持int64。 diff --git a/doc/fluid/beginners_guide/coding_practice/save_load_variables.rst b/doc/fluid/beginners_guide/coding_practice/save_load_variables.rst index 56f53792726cc4375f1e2706f9522590f3febd2c..6ce016d84eb8fded69675d4689fb684527ed608e 100644 --- a/doc/fluid/beginners_guide/coding_practice/save_load_variables.rst +++ b/doc/fluid/beginners_guide/coding_practice/save_load_variables.rst @@ -204,8 +204,8 @@ save_vars、save_params、save_persistables 以及 save_inference_model的区别 path = "./models" startup_prog = fluid.default_startup_program() exe.run(startup_prog) + fluid.io.load_persistables(exe, path, startup_prog) main_prog = fluid.default_main_program() - fluid.io.load_persistables(exe, path, main_prog) exe.run(main_prog) 上面的例子中,通过调用 :code:`fluid.io.load_persistables` 函数,PaddlePaddle Fluid会从默认 @@ -270,12 +270,12 @@ save_vars、save_params、save_persistables 以及 save_inference_model的区别 pserver_endpoints = "127.0.0.1:1001,127.0.0.1:1002" trainers = 4 training_role == "PSERVER" + current_endpoint = "127.0.0.1:1002" config = fluid.DistributeTranspilerConfig() t = fluid.DistributeTranspiler(config=config) t.transpile(trainer_id, pservers=pserver_endpoints, trainers=trainers, sync_mode=True, current_endpoint=current_endpoint) if training_role == "PSERVER": - current_endpoint = "127.0.0.1:1001" pserver_prog = t.get_pserver_program(current_endpoint) pserver_startup = t.get_startup_program(current_endpoint, pserver_prog) @@ -284,7 +284,7 @@ save_vars、save_params、save_persistables 以及 save_inference_model的区别 exe.run(pserver_prog) if training_role == "TRAINER": main_program = t.get_trainer_program() - exe.run(main_program) + exe.run(main_program) 上面的例子中,每个PServer通过调用HDFS的命令获取到0号trainer保存的参数,通过配置获取到PServer的 :code:`fluid.Program` ,PaddlePaddle Fluid会从此 :code:`fluid.Program` 也就是 :code:`pserver_startup` 的所有模型变量中找出长期变量,并通过指定的 :code:`path` 目录下一一加载。 diff --git a/doc/fluid/beginners_guide/coding_practice/save_load_variables_en.rst b/doc/fluid/beginners_guide/coding_practice/save_load_variables_en.rst index 2471ccfdf4607df5dc2591d99f6186949923fee9..7130cb03b579dd97ad64f02aa401ebd188047393 100644 --- a/doc/fluid/beginners_guide/coding_practice/save_load_variables_en.rst +++ b/doc/fluid/beginners_guide/coding_practice/save_load_variables_en.rst @@ -27,23 +27,6 @@ How to save model variables The model variables we need to save are different depending on the application. For example, if we just want to save the model for future predictions, just saving the model parameters will be enough. But if we need to save a checkpoint for future recovery of current training, then we should save all the persistable variables, and even record the current epoch and step id. It is because even though some model variables are not parameters, they are still essential for model training. - -Difference between save_vars、save_params、save_persistables and save_inference_model -########################################################################## -1. :code:`save_inference_model` will prune the inference model based on :code:`feeded_var_names` and :code:`target_vars` , this method will save the ``__model__`` file of the pruned program and the persistable variables in the program. - -2. :code:`save_persistables` this method will not save model, it will save all the persistable variables in the program. - -3. :code:`save_params` this method will not save model, it will save all the parameters in the program. - -4. :code:`save_vars` this method will not save model, it will save the given parameter by user. - - :code:`save_persistables` this method is useful for increment training or checkpoint training, it can save persistable variables in program comprehensively, such as parameter variables, optimizer variables, if you need increment training or checkpoint training, please choose this one. - :code:`save_inference_model` this method is useful for inference, it will save persistable variables and pruned program, if you need program and variables for follow-up high performance inference, please choose this one. - - :code:`save_vars 和 save_params` there methods are only needed in particular cases, we suppose you already know the purpose of there APIs, there are not recommended for use normally. - - Save the model to make prediction for new samples =================================================== @@ -143,8 +126,8 @@ In the above example, by calling the :code:`fluid.io.save_persistables` function path = "./models" startup_prog = fluid.default_startup_program() exe.run(startup_prog) + fluid.io.load_persistables(exe, path, startup_prog) main_prog = fluid.default_main_program() - fluid.io.load_persistables(exe, path, main_prog) exe.run(main_prog) In the above example, by calling the :code:`fluid.io.load_persistables` function, PaddlePaddle Fluid will find persistable variables from all model variables in the default :code:`fluid.Program` , e.t. :code:`prog` . and load them one by one from the specified :code:`path` directory to continue training. @@ -196,23 +179,23 @@ For the PServer to be loaded with parameters during training, for example: exe = fluid.Executor(fluid.CPUPlace()) path = "./models" - pserver_endpoints = "127.0.0.1:1001,127.0.0.1:1002" - trainers = 4 - Training_role == "PSERVER" - config = fluid.DistributeTranspilerConfig() - t = fluid.DistributeTranspiler(config=config) - t.transpile(trainer_id, pservers=pserver_endpoints, trainers=trainers, sync_mode=True) - - if training_role == "PSERVER": - current_endpoint = "127.0.0.1:1001" - pserver_prog = t.get_pserver_program(current_endpoint) - pserver_startup = t.get_startup_program(current_endpoint, pserver_prog) - - exe.run(pserver_startup) - fluid.io.load_persistables(exe, path, pserver_startup) - exe.run(pserver_prog) - if training_role == "TRAINER": - main_program = t.get_trainer_program() - exe.run(main_program) + pserver_endpoints = "127.0.0.1:1001,127.0.0.1:1002" + trainers = 4 + Training_role == "PSERVER" + current_endpoint = "127.0.0.1:1002" + config = fluid.DistributeTranspilerConfig() + t = fluid.DistributeTranspiler(config=config) + t.transpile(trainer_id, pservers=pserver_endpoints, trainers=trainers, sync_mode=True, current_endpoint=current_endpoint) + + if training_role == "PSERVER": + pserver_prog = t.get_pserver_program(current_endpoint) + pserver_startup = t.get_startup_program(current_endpoint, pserver_prog) + + exe.run(pserver_startup) + fluid.io.load_persistables(exe, path, pserver_startup) + exe.run(pserver_prog) + if training_role == "TRAINER": + main_program = t.get_trainer_program() + exe.run(main_program) In the above example, each PServer obtains the parameters saved by trainer 0 by calling the HDFS command, and obtains the PServer's :code:`fluid.Program` by configuration. PaddlePaddle Fluid will find all persistable variables in all model variables from this :code:`fluid.Program` , e.t. :code:`pserver_startup` , and load them from the specified :code:`path` directory. diff --git a/doc/fluid/beginners_guide/dygraph/DyGraph.md b/doc/fluid/beginners_guide/dygraph/DyGraph.md index 6d1089d50a84d0789a362ea5ae4068f8dcc2c414..d71c7bbfb4de4614931049a2ec855f152bd7e319 100644 --- a/doc/fluid/beginners_guide/dygraph/DyGraph.md +++ b/doc/fluid/beginners_guide/dygraph/DyGraph.md @@ -551,7 +551,7 @@ static_layer.save_inference_model(save_dirname, feed=[0], fetch=[0]) # 声明式编程中需要使用执行器执行之前已经定义好的网络 place = paddle.CPUPlace() exe = paddle.Executor(place) -program, feed_vars, fetch_vars = paddle.io.load_inference_model(save_dirname, exe) +program, feed_vars, fetch_vars = paddle.static.load_inference_model(save_dirname, exe) # 声明式编程中需要调用执行器的run方法执行计算过程 fetch, = exe.run(program, feed={feed_vars[0]: in_np}, fetch_list=fetch_vars) ``` diff --git a/doc/paddle/advanced_guide/inference_deployment/inference/build_and_install_lib_cn.rst b/doc/paddle/advanced_guide/inference_deployment/inference/build_and_install_lib_cn.rst index c1bfba460db6c12651ac6a04f823812642490c9f..9e255c3d92992c521262b9f78f157b247ab25631 100644 --- a/doc/paddle/advanced_guide/inference_deployment/inference/build_and_install_lib_cn.rst +++ b/doc/paddle/advanced_guide/inference_deployment/inference/build_and_install_lib_cn.rst @@ -7,16 +7,16 @@ ------------- .. csv-table:: - :header: "版本说明", "预测库(1.8.3版本)", "预测库(develop版本)" - :widths: 3, 2, 2 + :header: "版本说明", "预测库(1.8.4版本)", "预测库(2.0.0-beta0版本)", "预测库(develop版本)" + :widths: 3, 2, 2, 2 - "ubuntu14.04_cpu_avx_mkl", "`fluid_inference.tgz `_", "`fluid_inference.tgz `_" - "ubuntu14.04_cpu_avx_openblas", "`fluid_inference.tgz `_", "`fluid_inference.tgz `_" - "ubuntu14.04_cpu_noavx_openblas", "`fluid_inference.tgz `_", "`fluid_inference.tgz `_" - "ubuntu14.04_cuda9.0_cudnn7_avx_mkl", "`fluid_inference.tgz `_", "`fluid_inference.tgz `_" - "ubuntu14.04_cuda10.0_cudnn7_avx_mkl", "`fluid_inference.tgz `_", "`fluid_inference.tgz `_" - "ubuntu14.04_cuda10.1_cudnn7.6_avx_mkl_trt6", "`fluid_inference.tgz `_", - "nv-jetson-cuda10-cudnn7.5-trt5", "`fluid_inference.tar.gz `_", + "ubuntu14.04_cpu_avx_mkl", "`fluid_inference.tgz `_", "`paddle_inference.tgz `_", "`paddle_inference.tgz `_" + "ubuntu14.04_cpu_avx_openblas", "`fluid_inference.tgz `_", ,"`paddle_inference.tgz `_" + "ubuntu14.04_cpu_noavx_openblas", "`fluid_inference.tgz `_", ,"`paddle_inference.tgz `_" + "ubuntu14.04_cuda9.0_cudnn7_avx_mkl", "`fluid_inference.tgz `_", "`paddle_inference.tgz `_", "`paddle_inference.tgz `_" + "ubuntu14.04_cuda10.0_cudnn7_avx_mkl", "`fluid_inference.tgz `_", "`paddle_inference.tgz `_", "`paddle_inference.tgz `_" + "ubuntu14.04_cuda10.1_cudnn7.6_avx_mkl_trt6", "`fluid_inference.tgz `_", "`paddle_inference.tgz `_", + "nv-jetson-cuda10-cudnn7.5-trt5", "`fluid_inference.tar.gz `_", "`paddle_inference.tar.gz `_", 从源码编译 @@ -46,7 +46,7 @@ WITH_NV_JETSON OFF 在NV Jetson硬件上编译时需 git clone https://github.com/paddlepaddle/Paddle cd Paddle # 建议使用git checkout切换到Paddle稳定的版本,如: - git checkout v1.7.2 + git checkout v1.8.4 **note**: 如果您是多卡机器,建议安装NCCL;如果您是单卡机器则可以在编译时显示指定WITH_NCCL=OFF来跳过这一步。注意如果WITH_NCCL=ON,且没有安装NCCL,则编译会报错。 @@ -188,3 +188,4 @@ version.txt 中记录了该预测库的版本信息,包括Git Commit ID、使 WITH_GPU: ON CUDA version: 10.1 CUDNN version: v7 + diff --git a/doc/paddle/advanced_guide/inference_deployment/inference/build_and_install_lib_en.rst b/doc/paddle/advanced_guide/inference_deployment/inference/build_and_install_lib_en.rst index 545aba61360b0018e3d3a1c28f4e56f4f6005925..60d19b0906f002191fd76b00acfd023c0618420d 100644 --- a/doc/paddle/advanced_guide/inference_deployment/inference/build_and_install_lib_en.rst +++ b/doc/paddle/advanced_guide/inference_deployment/inference/build_and_install_lib_en.rst @@ -7,16 +7,16 @@ Direct Download and Installation --------------------------------- .. csv-table:: c++ inference library list - :header: "version description", "inference library(1.8.3 version)", "inference library(develop version)" - :widths: 3, 2, 2 + :header: "version description", "inference library(1.8.4 version)", "inference library(2.0.0-beta0 version)", "inference library(develop version)" + :widths: 3, 2, 2, 2 - "ubuntu14.04_cpu_avx_mkl", "`fluid_inference.tgz `_", "`fluid_inference.tgz `_" - "ubuntu14.04_cpu_avx_openblas", "`fluid_inference.tgz `_", "`fluid_inference.tgz `_" - "ubuntu14.04_cpu_noavx_openblas", "`fluid_inference.tgz `_", "`fluid_inference.tgz `_" - "ubuntu14.04_cuda9.0_cudnn7_avx_mkl", "`fluid_inference.tgz `_", "`fluid_inference.tgz `_" - "ubuntu14.04_cuda10.0_cudnn7_avx_mkl", "`fluid_inference.tgz `_", "`fluid_inference.tgz `_" - "ubuntu14.04_cuda10.1_cudnn7.6_avx_mkl_trt6", "`fluid_inference.tgz `_", - "nv-jetson-cuda10-cudnn7.5-trt5", "`fluid_inference.tar.gz `_", + "ubuntu14.04_cpu_avx_mkl", "`fluid_inference.tgz `_", "`paddle_inference.tgz `_", "`paddle_inference.tgz `_" + "ubuntu14.04_cpu_avx_openblas", "`fluid_inference.tgz `_", ,"`paddle_inference.tgz `_" + "ubuntu14.04_cpu_noavx_openblas", "`fluid_inference.tgz `_", ,"`paddle_inference.tgz `_" + "ubuntu14.04_cuda9.0_cudnn7_avx_mkl", "`fluid_inference.tgz `_", "`paddle_inference.tgz `_", "`paddle_inference.tgz `_" + "ubuntu14.04_cuda10.0_cudnn7_avx_mkl", "`fluid_inference.tgz `_", "`paddle_inference.tgz `_", "`paddle_inference.tgz `_" + "ubuntu14.04_cuda10.1_cudnn7.6_avx_mkl_trt6", "`fluid_inference.tgz `_", "`paddle_inference.tgz `_", + "nv-jetson-cuda10-cudnn7.5-trt5", "`fluid_inference.tar.gz `_", "`paddle_inference.tar.gz `_", Build from Source Code ----------------------- @@ -46,8 +46,8 @@ Firstly we pull the latest code from github. git clone https://github.com/paddlepaddle/Paddle cd Paddle - # Use git checkout to switch to stable versions such as v1.7.2 - git checkout v1.7.2 + # Use git checkout to switch to stable versions such as v1.8.4 + git checkout v1.8.4 **note**: If your environment is a multi-card machine, it is recommended to install nccl; otherwise, you can skip this step by specifying WITH_NCCL = OFF during compilation. Note that if WITH_NCCL = ON, and NCCL is not installed, the compiler will report an error. @@ -202,3 +202,4 @@ The version information of the inference library is recorded in version.txt, inc WITH_GPU: ON CUDA version: 8.0 CUDNN version: v7 + diff --git a/doc/paddle/advanced_guide/inference_deployment/inference/native_infer.md b/doc/paddle/advanced_guide/inference_deployment/inference/native_infer.md index 0c7d29ff2837b0dc54657dc45eb37250c7c90501..49ef48ce5e5141bb59490832faa2e33cf9e468c1 100644 --- a/doc/paddle/advanced_guide/inference_deployment/inference/native_infer.md +++ b/doc/paddle/advanced_guide/inference_deployment/inference/native_infer.md @@ -1,35 +1,37 @@ # C++ 预测 API介绍 -为了更简单方便地预测部署,PaddlePaddle 提供了一套高层 C++ API 预测接口。 - -下面是详细介绍。 +为了更简单方便地预测部署,PaddlePaddle 提供了一套高层 C++ API 预测接口。下面是详细介绍。 +如果您在使用2.0之前的Paddle,请参考[旧版API](https://www.paddlepaddle.org.cn/documentation/docs/zh/1.8/advanced_guide/inference_deployment/inference/native_infer.html)文档,升级到新版API请参考[推理升级指南](#推理升级指南)。 ## 内容 -- [使用AnalysisPredictor进行高性能预测](#使用AnalysisPredictor进行高性能预测) -- [使用AnalysisConfig管理预测配置](#使用AnalysisConfig管理预测配置) -- [使用ZeroCopyTensor管理输入/输出](#使用ZeroCopyTensor管理输入/输出) +- [使用Predictor进行高性能预测](#使用Predictor进行高性能预测) +- [使用Config管理预测配置](#使用Config管理预测配置) +- [使用Tensor管理输入/输出](#使用Tensor管理输入/输出) +- [使用PredictorPool在多线程下进行预测](#使用PredictorPool在多线程下进行预测) - [C++预测样例编译测试](#C++预测样例编译测试) - [性能调优](#性能调优) +- [推理升级指南](#推理升级指南) +- [C++ API](#C++_API) +## 使用Predictor进行高性能预测 -## 使用AnalysisPredictor进行高性能预测 -Paddle Fluid采用 AnalysisPredictor 进行预测。AnalysisPredictor 是一个高性能预测引擎,该引擎通过对计算图的分析,完成对计算图的一系列的优化(如OP的融合、内存/显存的优化、 MKLDNN,TensorRT 等底层加速库的支持等),能够大大提升预测性能。 +Paddle Inference采用 Predictor 进行预测。Predictor 是一个高性能预测引擎,该引擎通过对计算图的分析,完成对计算图的一系列的优化(如OP的融合、内存/显存的优化、 MKLDNN,TensorRT 等底层加速库的支持等),能够大大提升预测性能。 -为了展示完整的预测流程,下面是一个使用 AnalysisPredictor 进行预测的完整示例,其中涉及到的具体概念和配置会在后续部分展开详细介绍。 +为了展示完整的预测流程,下面是一个使用 Predictor 进行预测的完整示例,其中涉及到的具体概念和配置会在后续部分展开详细介绍。 -#### AnalysisPredictor 预测示例 +#### Predictor 预测示例 ``` c++ #include "paddle_inference_api.h" -namespace paddle { -void CreateConfig(AnalysisConfig* config, const std::string& model_dirname) { +namespace paddle_infer { +void CreateConfig(Config* config, const std::string& model_dirname) { // 模型从磁盘进行加载 - config->SetModel(model_dirname + "/model", - model_dirname + "/params"); + config->SetModel(model_dirname + "/model", + model_dirname + "/params"); // config->SetModel(model_dirname); // 如果模型从内存中加载,可以使用SetModelBuffer接口 // config->SetModelBuffer(prog_buffer, prog_size, params_buffer, params_size); @@ -41,22 +43,18 @@ void CreateConfig(AnalysisConfig* config, const std::string& model_dirname) { config->SetCpuMathLibraryNumThreads(10); */ - // 使用ZeroCopyTensor,此处必须设置为false - config->SwitchUseFeedFetchOps(false); - // 若输入为多个,此处必须设置为true - config->SwitchSpecifyInputNames(true); - config->SwitchIrDebug(true); // 可视化调试选项,若开启,则会在每个图优化过程后生成dot文件 - // config->SwitchIrOptim(false); // 默认为true。如果设置为false,关闭所有优化 - // config->EnableMemoryOptim(); // 开启内存/显存复用 + config->SwitchIrDebug(true); // 可视化调试选项,若开启,则会在每个图优化过程后生成dot文件 + // config->SwitchIrOptim(false); // 默认为true。如果设置为false,关闭所有优化 + // config->EnableMemoryOptim(); // 开启内存/显存复用 } void RunAnalysis(int batch_size, std::string model_dirname) { // 1. 创建AnalysisConfig - AnalysisConfig config; + Config config; CreateConfig(&config, model_dirname); // 2. 根据config 创建predictor,并准备输入数据,此处以全0数据为例 - auto predictor = CreatePaddlePredictor(config); + auto predictor = CreatePredictor(config); int channels = 3; int height = 224; int width = 224; @@ -65,50 +63,45 @@ void RunAnalysis(int batch_size, std::string model_dirname) { // 3. 创建输入 // 使用了ZeroCopy接口,可以避免预测中多余的CPU copy,提升预测性能 auto input_names = predictor->GetInputNames(); - auto input_t = predictor->GetInputTensor(input_names[0]); + auto input_t = predictor->GetInputHandle(input_names[0]); input_t->Reshape({batch_size, channels, height, width}); - input_t->copy_from_cpu(input); + input_t->CopyFromCpu(input); // 4. 运行预测引擎 - CHECK(predictor->ZeroCopyRun()); + CHECK(predictor->Run()); // 5. 获取输出 std::vector out_data; auto output_names = predictor->GetOutputNames(); - auto output_t = predictor->GetOutputTensor(output_names[0]); + auto output_t = predictor->GetOutputHandle(output_names[0]); std::vector output_shape = output_t->shape(); int out_num = std::accumulate(output_shape.begin(), output_shape.end(), 1, std::multiplies()); out_data.resize(out_num); - output_t->copy_to_cpu(out_data.data()); + output_t->CopyToCpu(out_data.data()); } -} // namespace paddle +} // namespace paddle_infer int main() { // 模型下载地址 http://paddle-inference-dist.cdn.bcebos.com/tensorrt_test/mobilenet.tar.gz - paddle::RunAnalysis(1, "./mobilenet"); + paddle_infer::RunAnalysis(1, "./mobilenet"); return 0; } - ``` -## 使用AnalysisConfig管理预测配置 +## 使用Config管理预测配置 -AnalysisConfig管理AnalysisPredictor的预测配置,提供了模型路径设置、预测引擎运行设备选择以及多种优化预测流程的选项。配置方法如下: +Config管理Predictor的预测配置,提供了模型路径设置、预测引擎运行设备选择以及多种优化预测流程的选项。配置方法如下: #### 通用优化配置 ``` c++ config->SwitchIrOptim(true); // 开启计算图分析优化,包括OP融合等 config->EnableMemoryOptim(); // 开启内存/显存复用 ``` -**Note:** 使用ZeroCopyTensor必须设置: -``` c++ -config->SwitchUseFeedFetchOps(false); // 关闭feed和fetch OP使用,使用ZeroCopy接口必须设置此项 -``` #### 设置模型和参数路径 -从磁盘加载模型时,根据模型和参数文件存储方式不同,设置AnalysisConfig加载模型和参数的路径有两种形式: +从磁盘加载模型时,根据模型和参数文件存储方式不同,设置Config加载模型和参数的路径有两种形式: * 非combined形式:模型文件夹`model_dir`下存在一个模型文件和多个参数文件时,传入模型文件夹路径,模型文件名默认为`__model__`。 ``` c++ @@ -124,43 +117,41 @@ config->SetModel("./model_dir/model", "./model_dir/params"); #### 配置CPU预测 ``` c++ -config->DisableGpu(); // 禁用GPU -config->EnableMKLDNN(); // 开启MKLDNN,可加速CPU预测 -config->SetCpuMathLibraryNumThreads(10); // 设置CPU Math库线程数,CPU核心数支持情况下可加速预测 +config->DisableGpu(); // 禁用GPU +config->EnableMKLDNN(); // 开启MKLDNN,可加速CPU预测 +config->SetCpuMathLibraryNumThreads(10); // 设置CPU Math库线程数,CPU核心数支持情况下可加速预测 ``` #### 配置GPU预测 ``` c++ config->EnableUseGpu(100, 0); // 初始化100M显存,使用GPU ID为0 config->GpuDeviceId(); // 返回正在使用的GPU ID // 开启TensorRT预测,可提升GPU预测性能,需要使用带TensorRT的预测库 -config->EnableTensorRtEngine(1 << 20 /*workspace_size*/, - batch_size /*max_batch_size*/, - 3 /*min_subgraph_size*/, - AnalysisConfig::Precision::kFloat32 /*precision*/, - false /*use_static*/, - false /*use_calib_mode*/); +config->EnableTensorRtEngine(1 << 20 /*workspace_size*/, + batch_size /*max_batch_size*/, + 3 /*min_subgraph_size*/, + AnalysisConfig::Precision::kFloat32 /*precision*/, + false /*use_static*/, + false /*use_calib_mode*/); ``` -## 使用ZeroCopyTensor管理输入/输出 +## 使用Tensor管理输入/输出 -ZeroCopyTensor是AnalysisPredictor的输入/输出数据结构。ZeroCopyTensor的使用可以避免预测时候准备输入以及获取输出时多余的数据copy,提高预测性能。 - -**Note:** 使用ZeroCopyTensor,务必在创建config时设置`config->SwitchUseFeedFetchOps(false);`。 +Tensor是Predictor的输入/输出数据结构。 ``` c++ -// 通过创建的AnalysisPredictor获取输入和输出的tensor +// 通过创建的Predictor获取输入和输出的tensor auto input_names = predictor->GetInputNames(); -auto input_t = predictor->GetInputTensor(input_names[0]); +auto input_t = predictor->GetInputHandle(input_names[0]); auto output_names = predictor->GetOutputNames(); -auto output_t = predictor->GetOutputTensor(output_names[0]); +auto output_t = predictor->GetOutputHandle(output_names[0]); // 对tensor进行reshape input_t->Reshape({batch_size, channels, height, width}); -// 通过copy_from_cpu接口,将cpu数据输入;通过copy_to_cpu接口,将输出数据copy到cpu -input_t->copy_from_cpu(input_data /*数据指针*/); -output_t->copy_to_cpu(out_data /*数据指针*/); +// 通过CopyFromCpu接口,将cpu数据输入;通过CopyToCpu接口,将输出数据copy到cpu +input_t->CopyFromCpu(input_data /*数据指针*/); +output_t->CopyToCpu(out_data /*数据指针*/); // 设置LOD std::vector> lod_data = {{0}, {0}}; @@ -172,13 +163,29 @@ int output_size; float *output_d = output_t->data(PaddlePlace::kGPU, &output_size); ``` +## 使用PredictorPool在多线程下进行预测 + +`PredictorPool`对`Predictor`进行管理。`PredictorPool`对`Predictor`进行了简单的封装,通过传入config和thread的数目来完成初始化,在每个线程中,根据自己的线程id直接从池中取出对应的`Predictor`来完成预测过程。 + +```c++ +# 服务初始化时,完成PredictorPool的初始化 +PredictorPool pool(config, thread_num); + +# 根据线程id来获取Predictor +auto predictor = pool.Retrive(thread_id); + +# 使用Predictor进行预测 +... +``` + ## C++预测样例编译测试 + 1. 下载或编译paddle预测库,参考[安装与编译C++预测库](./build_and_install_lib_cn.html)。 2. 下载[预测样例](https://paddle-inference-dist.bj.bcebos.com/tensorrt_test/paddle_inference_sample_v1.7.tar.gz)并解压,进入`sample/inference`目录下。 - `inference` 文件夹目录结构如下: + `inference` 文件夹目录结构如下: - ``` shell + ``` shell inference ├── CMakeLists.txt ├── mobilenet_test.cc @@ -188,12 +195,12 @@ float *output_d = output_t->data(PaddlePlace::kGPU, &output_size); │ └── params ├── run.sh └── run_impl.sh - ``` + ``` - - `mobilenet_test.cc` 为单线程预测的C++源文件 - - `thread_mobilenet_test.cc` 为多线程预测的C++源文件 - - `mobilenetv1` 为模型文件夹 - - `run.sh` 为预测运行脚本文件 + - `mobilenet_test.cc` 为单线程预测的C++源文件 + - `thread_mobilenet_test.cc` 为多线程预测的C++源文件 + - `mobilenetv1` 为模型文件夹 + - `run.sh` 为预测运行脚本文件 3. 配置编译与运行脚本 @@ -217,11 +224,12 @@ float *output_d = output_t->data(PaddlePlace::kGPU, &output_size); 4. 编译与运行样例 - ``` shell - sh run.sh - ``` + ``` shell + sh run.sh + ``` ## 性能调优 + ### CPU下预测 1. 在CPU型号允许的情况下,尽量使用带AVX和MKL的版本。 2. 可以尝试使用Intel的 MKLDNN 加速。 @@ -231,7 +239,7 @@ float *output_d = output_t->data(PaddlePlace::kGPU, &output_size); 1. 可以尝试打开 TensorRT 子图加速引擎, 通过计算图分析,Paddle可以自动将计算图中部分子图融合,并调用NVIDIA的 TensorRT 来进行加速,详细内容可以参考 [使用Paddle-TensorRT库预测](../../performance_improving/inference_improving/paddle_tensorrt_infer.html)。 ### 多线程预测 -Paddle Fluid支持通过在不同线程运行多个AnalysisPredictor的方式来优化预测性能,支持CPU和GPU环境。 +Paddle Inference支持通过在不同线程运行多个Predictor的方式来优化预测性能,支持CPU和GPU环境。 使用多线程预测的样例详见[C++预测样例编译测试](#C++预测样例编译测试)中下载的[预测样例](https://paddle-inference-dist.bj.bcebos.com/tensorrt_test/paddle_inference_sample_v1.7.tar.gz)中的 `thread_mobilenet_test.cc`文件。可以将`run.sh`中`mobilenet_test`替换成`thread_mobilenet_test`再执行 @@ -241,3 +249,1233 @@ sh run.sh ``` 即可运行多线程预测样例。 + +## 推理升级指南 + +2.0对API做了整理,简化了写法,以及去掉了历史上冗余的概念。 + +新的 API 为纯增,原有 API 保持不变,在后续版本会逐步删除。 + +重要变化: + +- 命名空间从 `paddle` 变更为 `paddle_infer` +- `PaddleTensor`, `PaddleBuf` 等被废弃,`ZeroCopyTensor` 变为默认 Tensor 类型,并更名为 `Tensor` +- 新增 `PredictorPool` 工具类简化多线程 predictor 的创建,后续也会增加更多周边工具 +- `CreatePredictor` (原 `CreatePaddlePredictor`) 的返回值由 `unique_ptr` 变为 `shared_ptr` 以避免 Clone 后析构顺序出错的问题 + +API 变更 + +| 原有命名 | 现有命名 | 行为变化 | +| ---------------------------- | ---------------------------- | ----------------------------- | +| 头文件 `paddle_infer.h` | 无变化 | 包含旧接口,保持向后兼容 | +| 无 | `paddle_inference_api.h` | 新API,可以与旧接口并存 | +| `CreatePaddlePredictor` | `CreatePredictor` | 返回值变为 shared_ptr | +| `ZeroCopyTensor` | `Tensor` | 无 | +| `AnalysisConfig` | `Config` | 无 | +| `TensorRTConfig` | 废弃 | | +| `PaddleTensor` + `PaddleBuf` | 废弃 | | +| `Predictor::GetInputTensor` | `Predictor::GetInputHandle` | 无 | +| `Predictor::GetOutputTensor` | `Predictor::GetOutputHandle` | 无 | +| | `PredictorPool` | 简化创建多个 predictor 的支持 | + +使用新 C++ API 的流程与之前完全一致,只有命名变化 + +```c++ +#include "paddle_infernce_api.h" +using namespace paddle_infer; + +Config config; +config.SetModel("xxx_model_dir"); + +auto predictor = CreatePredictor(config); + +// Get the handles for the inputs and outputs of the model +auto input0 = predictor->GetInputHandle("X"); +auto output0 = predictor->GetOutputHandle("Out"); + +for (...) { + // Assign data to input0 + MyServiceSetData(input0); + + predictor->Run(); + + // get data from the output0 handle + MyServiceGetData(output0); +} +``` + +## C++ API + +##### CreatePredictor + +```c++ +std::shared_ptr CreatePredictor(const Config& config); +``` + +`CreatePredictor`用来根据`Config`构建预测引擎。 + +示例: + +```c++ +// 设置Config +Config config; +config.SetModel(FLAGS_model_dir); + +// 根据Config创建Predictor +std::shared_ptr predictor = CreatePredictor(config); +``` + +参数: + +- `config(Config)` - 用于构建Predictor的配置信息 + +返回:`Predictor`智能指针 + +返回类型:`std::shared_ptr` + +##### GetVersion() + +```c++ +std::string GetVersion(); +``` + +打印Paddle Inference的版本信息。 + +参数: + +- `None` + +返回:版本信息 + +返回类型:`std::string` + +##### PlaceType + +```c++ +enum class PaddlePlace { kUNK }; +using PlaceType = paddle::PaddlePlace; +``` + +PlaceType为目标设备硬件类型,用户可以根据应用场景选择硬件平台类型。 + +枚举变量`PlaceType`的所有可能取值包括: + +`{kUNK, kCPU, kGPU}` + +##### PrecisionType + +```c++ +enum class Precision { kFloat32 }; +using PrecisionType = paddle::AnalysisConfig::Precision; +``` + +`PrecisionType`设置模型的运行精度,默认值为kFloat32(float32)。 + +枚举变量`PrecisionType`的所有可能取值包括: + +`{kFloat32, kInt8, kHalf}` + +##### DataType + +```c++ +enum class PaddleDType { FLOAT32 }; +using DataType = paddle::PaddleDType; +``` + +`DataType`为模型中Tensor的数据精度,默认值为FLOAT32(float32)。 + +枚举变量`DataType`的所有可能取值包括: + +`{FLOAT32, INT64, INT32, UINT8}` + +##### GetNumBytesOfDataType + +```c++ +int GetNumBytesOfDataType(DataType dtype); +``` + +获取各个`DataType`对应的字节数。 + +参数: + +- `dtype` - DataType枚举 + +返回:字节数 + +返回类型:`int` + + +##### Predictor + +```c++ +class Predictor; +``` + +`Predictor`是Paddle Inference的预测器,由`CreatePredictor`根据`Config`进行创建。用户可以根据Predictor提供的接口设置输入数据、执行模型预测、获取输出等. + +示例: + +```c++ +using namespace paddle_infer; + +Config config; +config.SetModel("xxx_model_dir"); + +auto predictor = CreatePredictor(config); + +// Get the handles for the inputs and outputs of the model +auto input0 = predictor->GetInputHandle("X"); +auto output0 = predictor->GetOutputHandle("Out"); + +for (...) { + // Assign data to input0 + MyServiceSetData(input0); + + predictor->Run(); + + // get data from the output0 handle + MyServiceGetData(output0); +} +``` + +###### GetInputNames() + +获取所有输入Tensor的名称。 + +参数: + +- `None` + +返回:所有输入Tensor的名称 + +返回类型:`std::vector` + +###### GetOutputNames() + +获取所有输出Tensor的名称。 + +参数: + +- `None` + +返回:所有输出Tensor的名称 + +返回类型:`std::vector` + +###### GetInputHandle(const std::string& name) + +根据名称获取输入Tensor的句柄。 + +参数: + +- `name` - Tensor的名称 + +返回:指向`Tensor`的指针 + +返回类型:`std::unique_ptr` + +###### GetOutputHandle(const std::string& name) + +根据名称获取输出Tensor的句柄。 + +参数: + +- `name` - Tensor的名称 + +返回:指向`Tensor`的指针 + +返回类型:`std::unique_ptr` + +###### Run() + +执行模型预测,需要在***设置输入数据后***调用。 + +参数: + +- `None` + +返回:`None` + +返回类型:`void` + +###### ClearIntermediateTensor() + +释放中间tensor。 + +参数: + +- `None` + +返回:`None` + +返回类型:`void` + +###### Clone() + +根据该Predictor,克隆一个新的Predictor,两个Predictor之间共享权重。 + +参数: + +- `None` + +返回:新的Predictor + +返回类型:`std::unique_ptr` + + +##### Tensor + +```c++ +class Tensor; +``` + +Tensor是Paddle Inference的数据组织形式,用于对底层数据进行封装并提供接口对数据进行操作,包括设置Shape、数据、LoD信息等。 + +*注意:用户应使用`Predictor`的`GetInputHandle`和`GetOuputHandle`接口获取输入/输出的`Tensor`。* + +示例: + +```c++ +// 通过创建的Predictor获取输入和输出的tensor +auto input_names = predictor->GetInputNames(); +auto input_t = predictor->GetInputHandle(input_names[0]); +auto output_names = predictor->GetOutputNames(); +auto output_t = predictor->GetOutputHandle(output_names[0]); + +// 对tensor进行reshape +input_t->Reshape({batch_size, channels, height, width}); + +// 通过CopyFromCpu接口,将cpu数据输入;通过CopyToCpu接口,将输出数据copy到cpu +input_t->CopyFromCpu(input_data /*数据指针*/); +output_t->CopyToCpu(out_data /*数据指针*/); + +// 设置LOD +std::vector> lod_data = {{0}, {0}}; +input_t->SetLoD(lod_data); + +// 获取Tensor数据指针 +float *input_d = input_t->mutable_data(PlaceType::kGPU); // CPU下使用PlaceType::kCPU +int output_size; +float *output_d = output_t->data(PlaceType::kGPU, &output_size); +``` + +###### Reshape(shape) + +设置Tensor的维度信息。 + +参数: + +- `shape(const std::vector&)` - 维度信息 + +返回:`None` + +返回类型:`void` + +###### shape() + +获取Tensor的维度信息。 + +参数: + +- `None` + +返回:Tensor的维度信息 + +返回类型:`std::vector` + +###### CopyFromCpu(data) + +```c++ +template +void CopyFromCpu(const T* data); +``` + +从cpu获取数据,设置到tensor内部。 + +示例: + +```c++ +// float* data = ...; +auto in_tensor = predictor->GetInputHandle("in_name"); +in_tensor->CopyFromCpu(data); +``` + +参数: + +- `data(const T*)` - cpu数据指针 + +返回:`None` + +返回类型:`void` + +###### CopyToCpu(data) + +```c++ +template +void CopyToCpu(T* data); +``` + +示例: + +```c++ +std::vector data(100); +auto out_tensor = predictor->GetOutputHandle("out_name"); +out_tensor->CopyToCpu(data.data()); +``` + +参数: + +- `data(T*)` - cpu数据指针 + +返回:`None` + +返回类型:`void` + + +###### data(place, size) + +```c++ +template +T* data(PlaceType* place, int* size) const; +``` + +获取Tensor的底层数据的常量指针,用于读取Tensor数据。 + +示例: + +```c++ +PlaceType place; +int size; +auto out_tensor = predictor->GetOutputHandle("out_name"); +float* data = out_tensor->data(&place, &size); +``` + +参数: + +- `place(PlaceType*)` - 获取tensor的PlaceType +- `size(int*)` - 获取tensor的size + +返回:数据指针 + +返回类型:`T*` + +###### mutable_data(place) + +```c++ +template +T* mutable_data(PlaceType place); +``` + +获取Tensor的底层数据的指针,用于设置Tensor数据。 + +```c++ +auto in_tensor = predictor->GetInputHandle("in_name"); +float* data = out_tensor->mutable_data(PlaceType::kCPU); +data[0] = 1.; +``` + +参数: + +- `place(PlaceType)` - 设备信息 + +返回:`Tensor`底层数据指针 + +返回类型:`T*` + +###### SetLoD(lod) + +设置Tensor的LoD信息。 + +参数: + +- `lod(const std::vector>)` - Tensor的LoD信息 + +返回:`None` + +返回类型:`void` + +###### lod() + +获取Tensor的LoD信息 + +参数: + +- `None` + +返回:`Tensor`的LoD信息 + +返回类型:`std::vector>` + +###### type() + +tensor的DataType信息。 + +参数: + +- `None` + +返回:`Tensor`的DataType信息 + +返回类型:`DataType` + +###### name() + +tensor对应的name。 + +参数: + +- `None` + +返回:`Tensor`对应的name + +返回类型:`std::string` + +##### Config + +```c++ +class Config; +``` + +`Config`用来配置构建`Predictor`的配置信息,如模型路径、是否开启gpu等等。 + +示例: + +```c++ +Config config; +config.SetModel(FLAGS_model_dir); +config.DisableGpu(); +config->SwitchIrOptim(false); // 默认为true。如果设置为false,关闭所有优化 +config->EnableMemoryOptim(); // 开启内存/显存复用 +``` + +###### SetModel(const std::string& model_dir) + +设置模型文件路径,当需要从磁盘加载非combine模式时使用。 + +参数: + +- `model_dir` - 模型文件夹路径 + +返回:`None` + +返回类型:`void` + + +###### model_dir() + +获取模型文件夹路径。 + +参数: + +- `None` + +返回:模型文件夹路径 + +返回类型:`string` + + +###### SetModel(const std::string& prog, const std::string& params) + +设置模型文件路径,当需要从磁盘加载combine模式时使用。 + +参数: + +- `prog` - 模型文件路径 +- `params` - 模型参数文件路径 + +返回:`None` + +返回类型:`void` + +###### SetProgFile(const std::string& prog) + +设置模型文件路径。 + +参数: + +- `prog` - 模型文件路径 + +返回:`None` + +返回类型:`void` + +###### prog_file() + +获取模型文件路径。 + +参数: + +- `None` + +返回:模型文件路径 + +返回类型:`string` + +###### SetParamsFile(const std::string& params) + +设置模型参数文件路径。 + +参数: + +- `params` - 模型文件路径 + +返回:`None` + +返回类型:`void` + +###### params_file() + +获取模型参数文件路径。 + +参数: + +- `None` + +返回:模型参数文件路径 + +返回类型:`string` + +###### SetModelBuffer(const char* prog_buffer, size_t prog_buffer_size, const char* params_buffer, size_t params_buffer_size) + +从内存加载模型。 + +参数: + +- `prog_buffer` - 内存中模型结构数据 +- `prog_buffer_size` - 内存中模型结构数据的大小 +- `params_buffer` - 内存中模型参数数据 +- `params_buffer_size` - 内存中模型参数数据的大小 + +返回:`None` + +返回类型:`void` + +###### model_from_memory() + +判断是否从内存中加载模型。 + +参数: + +- `None` + +返回:是否从内存中加载模型 + +返回类型:`bool` + +###### SetOptimCacheDir(const std::string& opt_cache_dir) + +设置缓存路径。 + +参数: + +- `opt_cache_dir` - 缓存路径 + +返回:`None` + +返回类型:`void` + +###### DisableFCPadding() + +关闭fc padding。 + +参数: + +- `None` + +返回:`None` + +返回类型:`void` + +###### use_fc_padding() + +判断是否启用fc padding。 + +参数: + +- `None` + +返回:是否启用fc padding + +返回类型:`bool` + +###### EnableUseGpu(uint64_t memory_pool_init_size_mb, int device_id = 0) + +启用gpu。 + +参数: + +- `memory_pool_init_size_mb` - 初始化分配的gpu显存,以MB为单位 +- `device_id` - 设备id + +返回:`None` + +返回类型:`void` + +###### DisableGpu() + +禁用gpu。 + +参数: + +- `None` + +返回:`None` + +返回类型:`void` + +###### use_gpu() + +是否启用gpu。 + +参数: + +- `None` + +返回:是否启用gpu + +返回类型:`bool` + +###### gpu_device_id() + +获取gpu的device id。 + +参数: + +- `None` + +返回:gpu的device id + +返回类型:`int` + +###### memory_pool_init_size_mb() + +获取gpu的初始显存大小。 + +参数: + +- `None` + +返回:初始的显存大小 + +返回类型:`int` + +###### fraction_of_gpu_memory_for_pool() + +初始化显存占总显存的百分比 + +参数: + +- `None` + +返回:初始的显存占总显存的百分比 + +返回类型:`float` + +###### EnableCUDNN() + +启用cudnn。 + +参数: + +- `None` + +返回:`None` + +返回类型:`void` + +###### cudnn_enabled() + +是否启用cudnn。 + +参数: + +- `None` + +返回:是否启用cudnn + +返回类型:`bool` + +###### EnableXpu(int l3_workspace_size) + +启用xpu。 + +参数: + +- `l3_workspace_size` - l3 cache分配的显存大小 + +返回:`None` + +返回类型:`void` + +###### SwitchIrOptim(int x=true) + +设置是否开启ir优化。 + +参数: + +- `x` - 是否开启ir优化,默认打开 + +返回:`None` + +返回类型:`void` + +###### ir_optim() + +是否开启ir优化。 + +参数: + +- `None` + +返回:是否开启ir优化 + +返回类型:`bool` + +###### SwitchUseFeedFetchOps(int x = true) + +设置是否使用feed,fetch op,仅内部使用。 + +参数: + +- `x` - 是否使用feed, fetch op + +返回:`None` + +返回类型:`void` + +###### use_feed_fetch_ops_enabled() + +是否使用feed,fetch op。 + +参数: + +- `None` + +返回:是否使用feed,fetch op + +返回类型:`bool` + +###### SwitchSpecifyInputNames(bool x = true) + +设置是否需要指定输入tensor的name。 + +参数: + +- `x` - 是否指定输入tensor的name + +返回:`None` + +返回类型:`void` + +###### specify_input_name() + +是否需要指定输入tensor的name。 + +参数: + +- `None` + +返回:是否需要指定输入tensor的name + +返回类型:`bool` + +###### EnableTensorRtEngine(int workspace_size = 1 << 20, int max_batch_size = 1, int min_subgraph_size = 3, Precision precision = Precision::kFloat32, bool use_static = false, bool use_calib_mode = true) + +设置是否启用TensorRT。 + +参数: + +- `workspace_size` - 指定TensorRT使用的工作空间大小 +- `max_batch_size` - 设置最大的batch大小,运行时batch大小不得超过此限定值 +- `min_subgraph_size` - Paddle-TRT是以子图的形式运行,为了避免性能损失,当子图内部节点个数大于min_subgraph_size的时候,才会使用Paddle-TRT运行 +- `precision` - 指定使用TRT的精度,支持FP32(kFloat32),FP16(kHalf),Int8(kInt8) +- `use_static` - 如果指定为true,在初次运行程序的时候会将TRT的优化信息进行序列化到磁盘上,下次运行时直接加载优化的序列化信息而不需要重新生成 +- `use_calib_mode` - 若要运行Paddle-TRT int8离线量化校准,需要将此选项设置为true + +返回:`None` + +返回类型:`void` + +###### tensorrt_engine_enabled() + +是否启用tensorRT。 + +参数: + +- `None` + +返回:是否启用tensorRT + +返回类型:`bool` + +###### SetTRTDynamicShapeInfo(std::map> min_input_shape, std::map> max_input_shape, std::map> optim_input_shape, bool disable_trt_plugin_fp16 = false) + +设置tensorRT的动态shape。 + +参数: + +- `min_input_shape` - tensorRT子图支持动态shape的最小shape +- `max_input_shape` - tensorRT子图支持动态shape的最大shape +- `optim_input_shape` - tensorRT子图支持动态shape的最优shape +- `disable_trt_plugin_fp16` - 设置tensorRT的plugin不在fp16精度下运行 + +返回:`None` + +返回类型:`void` + +###### EnableLiteEngine(AnalysisConfig::Precision precision_mode = Precsion::kFloat32, bool zero_copy = false, const std::vector& passes_filter = {}, const std::vector& ops_filter = {}) + +启用lite子图。 + +参数: + +- `precision_mode` - lite子图的运行精度 +- `zero_copy` - 启用zero_copy,lite子图与paddle inference之间共享数据 +- `passes_filter` - 设置lite子图的pass +- `ops_filter` - 设置不使用lite子图运行的op + +返回:`None` + +返回类型:`void` + +###### lite_engine_enabled() + +是否启用lite子图。 + +参数: + +- `None` + +返回:是否启用lite子图 + +返回类型:`bool` + +###### SwitchIrDebug(int x = true) + +设置是否在图分析阶段打印ir,启用后会在每一个pass后生成dot文件。 + +参数: + +- `x` - 是否打印ir + +返回:`None` + +返回类型:`void` + +###### EnableMKLDNN() + +启用mkldnn。 + +参数: + +- `None` + +返回:`None` + +返回类型:`void` + +###### SetMkldnnCacheCapacity(int capacity) + +设置mkldnn针对不同输入shape的cache容量大小,MKLDNN cache设计文档请参考[链接](https://github.com/PaddlePaddle/FluidDoc/blob/develop/doc/fluid/design/mkldnn/caching/caching.md) + +参数: + +- `capacity` - cache容量大小 + +返回:`None` + +返回类型:`void` + +###### mkldnn_enabled() + +是否启用mkldnn。 + +参数: + +- `None` + +返回:是否启用mkldnn + +返回类型:`bool` + +###### SetMKLDNNOp(std::unordered_set op_list) + +指定优先使用mkldnn加速的op列表。 + +参数: + +- `op_list` - 优先使用mkldnn的op列表 + +返回:`None` + +返回类型:`void` + +###### EnableMkldnnQuantizer() + +启用mkldnn量化。 + +参数: + +- `None` + +返回:`None` + +返回类型:`void` + +###### mkldnn_quantizer_enabled() + +是否启用mkldnn量化。 + +参数: + +- `None` + +返回:是否启用mkldnn量化 + +返回类型:`bool` + +###### EnableMkldnnBfloat16() + +启用mkldnn bf16。 + +参数: + +- `None` + +返回:`None` + +返回类型:`void` + +###### mkldnn_bfloat16_enabled() + +是否启用mkldnn bf16。 + +参数: + +- `None` + +返回:是否启用mkldnn bf16 + +返回类型:`bool` + +###### mkldnn_quantizer_config() + +返回mkldnn量化config。 + +参数: + +- `None` + +返回:mkldnn量化config + +返回类型:`MkldnnQuantizerConfig` + +###### SetCpuMathLibraryNumThreads(int cpu_math_library_num_threads) + +设置cpu blas库计算线程数。 + +参数: + +- `cpu_math_library_num_threads` - blas库计算线程数 + +返回:`None` + +返回类型:`void` + +###### cpu_math_library_num_threads() + +cpu blas库计算线程数。 + +参数: + +- `None` + +返回:cpu blas库计算线程数。 + +返回类型:`int` + +###### ToNativeConfig() + +转化为NativeConfig,不推荐使用。 + +参数: + +- `None` + +返回:当前Config对应的NativeConfig + +返回类型:`NativeConfig` + +###### EnableGpuMultiStream() + +开启线程流,目前的行为是为每一个线程绑定一个流,在将来该行为可能改变。 + +参数: + +- `None` + +返回:`None` + +返回类型:`void` + +###### thread_local_stream_enabled() + +是否启用线程流。 + +参数: + +- `None` + +返回:是否启用线程流。 + +返回类型:`bool` + +###### EnableMemoryOptim() + +开启内/显存复用,具体降低内存效果取决于模型结构。 + +参数: + +- `None` + +返回:`None` + +返回类型:`void` + +###### enable_memory_optim() + +是否开启内/显存复用。 + +参数: + +- `None` + +返回:是否开启内/显存复用。 + +返回类型:`bool` + +###### EnableProfile() + +打开profile,运行结束后会打印所有op的耗时占比。 + +参数: + +- `None` + +返回:`None` + +返回类型:`void` + +###### profile_enabled() + +是否开启profile。 + +参数: + +- `None` + +返回:是否开启profile + +返回类型:`bool` + +###### DisableGlogInfo() + +去除Paddle Inference运行中的log。 + +参数: + +- `None` + +返回:`None` + +返回类型:`void` + +###### glog_info_disabled() + +是否禁用了log。 + +参数: + +- `None` + +返回:是否禁用了log + +返回类型:`bool` + +###### SetInValid() + +设置Config为无效状态,仅内部使用,保证每一个Config仅用来初始化一次Predictor。 + +参数: + +- `None` + +返回:`None` + +返回类型:`void` + +###### is_valid() + +当前Config是否有效。 + +参数: + +- `None` + +返回:Config是否有效 + +返回类型:`bool` + +###### pass_builder() + +返回pass_builder,用来自定义图分析阶段选择的ir。 + +示例: + +```c++ +Config config; +auto pass_builder = config.pass_builder() +pass_builder->DeletePass("fc_fuse_pass") // 去除fc_fuse +``` + +参数: + +- `None` + +返回:pass_builder + +返回类型:`PassStrategy` + +##### PredictorPool + +```c++ +class PredictorPool; +``` + +`PredictorPool`对`Predictor`进行了简单的封装,通过传入config和thread的数目来完成初始化,在每个线程中,根据自己的线程id直接从池中取出对应的`Predictor`来完成预测过程。 + +示例: + +```c++ +Config config; +// init config +int thread_num = 4; + +PredictorPool pool(config, thread_num); + +auto predictor0 = pool.Retrive(0); +... +auto predictor3 = pool.Retrive(3); +``` + +###### Retrive(idx) + +根据线程id取出该线程对应的Predictor。 + +参数: + +- `idx(int)` - 线程id + +返回:线程对应的Predictor + +返回类型:`Predictor*` diff --git a/doc/paddle/advanced_guide/inference_deployment/inference/python_infer_cn.md b/doc/paddle/advanced_guide/inference_deployment/inference/python_infer_cn.md index c947b3d8ea9eec7a034a6f2d701c38036ec518ff..b0004c2eeb9bab42bee1affb1bdeeedbe78b19a3 100644 --- a/doc/paddle/advanced_guide/inference_deployment/inference/python_infer_cn.md +++ b/doc/paddle/advanced_guide/inference_deployment/inference/python_infer_cn.md @@ -1,63 +1,73 @@ # Python 预测 API介绍 -Fluid提供了高度优化的[C++预测库](./native_infer.html),为了方便使用,我们也提供了C++预测库对应的Python接口,下面是详细的使用说明。 - +Paddle提供了高度优化的[C++预测库](./native_infer.html),为了方便使用,我们也提供了C++预测库对应的Python接口,下面是详细的使用说明。 +如果您在使用2.0之前的Paddle,请参考[旧版API](https://www.paddlepaddle.org.cn/documentation/docs/zh/1.8/advanced_guide/inference_deployment/inference/python_infer_cn.html)文档。 ## Python预测相关数据结构 -使用Python预测API与C++预测API相似,主要包括`PaddleTensor`, `PaddleDType`, `AnalysisConfig`和`PaddlePredictor`,分别对应于C++ API中同名的类型。 +使用Python预测API与C++预测API相似,主要包括`Tensor`, `DataType`, `Config`和`Predictor`,分别对应于C++ API中同名的类型。 -### PaddleTensor +### DataType -class paddle.fluid.core.PaddleTensor +class paddle.inference.DataType -`PaddleTensor`是预测库输入和输出的数据结构,包括以下字段 +`DataType`定义了`Tensor`的数据类型,由传入`Tensor`的numpy数组类型确定,包括以下成员 -* `name`(str): 指定输入的名称 -* `shape`(tuple|list): Tensor的shape -* `data`(numpy.ndarray): Tensor的数据,可在PaddleTensor构造的时候用`numpy.ndarray`直接传入 -* `dtype`(PaddleDType): Tensor的类型 -* `lod`(List[List[int]]): [LoD](../../../user_guides/howto/basic_concept/lod_tensor.html)信息 +* `INT64`: 64位整型 +* `INT32`: 32位整型 +* `FLOAT32`: 32位浮点型 -`PaddleTensor`包括以下方法 +### PrecisionType -* `as_ndarray`: 返回`data`对应的numpy数组 +class paddle.3.inference.PrecisionType -#### 代码示例 -``` python -tensor = PaddleTensor(name="tensor", data=numpy.array([1, 2, 3], dtype="int32")) -``` -调用`PaddleTensor`的成员字段和方法输出如下: -``` python ->>> tensor.name -'tensor' ->>> tensor.shape -[3] ->>> tensor.dtype -PaddleDType.INT32 ->>> tensor.lod -[] ->>> tensor.as_ndarray() -array([1, 2, 3], dtype=int32) -``` +`PrecisionType`定义了`Predictor`运行的精度模式,包括一下成员 +* `Float32`: fp32模式运行 +* `Half`: fp16模式运行 +* `Int8`: int8模式运行 -### PaddleDType +### Tensor -class paddle.fluid.core.PaddleTensor +class paddle.inference.Tensor -`PaddleDType`定义了`PaddleTensor`的数据类型,由传入`PaddleTensor`的numpy数组类型确定,包括以下成员 +`Tensor`是`Predictor`的一种输入/输出数据结构,通过`predictor`获取输入/输出handle得到,主要提供以下方法 -* `INT64`: 64位整型 -* `INT32`: 32位整型 -* `FLOAT32`: 32位浮点型 +* `copy_from_cpu`: 从cpu获取模型运行所需输入数据 +* `copy_to_cpu`: 获取模型运行输出结果 +* `lod`: 获取lod信息 +* `set_lod`: 设置lod信息 +* `shape`: 获取shape信息 +* `reshape`: 设置shape信息 +* `type`: 获取DataType信息 -### AnalysisConfig +``` python +# 创建predictor +predictor = create_predictor(config) -class paddle.fluid.core.AnalysisConfig +# 获取输入的名称 +input_names = predictor.get_input_names() +input_tensor = predictor.get_input_handle(input_names[0]) -`AnalysisConfig`是创建预测引擎的配置,提供了模型路径设置、预测引擎运行设备选择以及多种优化预测流程的选项,主要包括以下方法 +# 设置输入 +fake_input = numpy.random.randn(1, 3, 318, 318).astype("float32") +input_tensor.copy_from_cpu(fake_input) + +# 运行predictor +predictor.run() + +# 获取输出 +output_names = predictor.get_output_names() +output_tensor = predictor.get_output_handle(output_names[0]) +output_data = output_tensor.copy_to_cpu() # numpy.ndarray类型 +``` + +### Config + +class paddle.inference.Config + +`Config`是创建预测引擎的配置,提供了模型路径设置、预测引擎运行设备选择以及多种优化预测流程的选项,主要包括以下方法 * `set_model`: 设置模型的路径 * `model_dir`: 返回模型文件夹路径 @@ -71,15 +81,16 @@ class paddle.fluid.core.AnalysisConfig * `enable_mkldnn`: 开启MKLDNN * `disable_glog_info`: 禁用预测中的glog日志 * `delete_pass`: 预测的时候删除指定的pass + #### 代码示例 设置模型和参数路径有两种形式: * 当模型文件夹下存在一个模型文件和多个参数文件时,传入模型文件夹路径,模型文件名默认为`__model__` ``` python -config = AnalysisConfig("./model") +config = Config("./model") ``` * 当模型文件夹下只有一个模型文件和一个参数文件时,传入模型文件和参数文件路径 ``` python -config = AnalysisConfig("./model/model", "./model/params") +config = Config("./model/model", "./model/params") ``` 使用`set_model`方法设置模型和参数路径方式同上 @@ -87,147 +98,53 @@ config = AnalysisConfig("./model/model", "./model/params") ``` python config.enable_use_gpu(100, 0) # 初始化100M显存,使用gpu id为0 config.gpu_device_id() # 返回正在使用的gpu id -config.disable_gpu() # 禁用gpu +config.disable_gpu() # 禁用gpu config.switch_ir_optim(True) # 开启IR优化 -config.enable_tensorrt_engine(precision_mode=AnalysisConfig.Precision.Float32, +config.enable_tensorrt_engine(precision_mode=PrecisionType.Float32, use_calib_mode=True) # 开启TensorRT预测,精度为fp32,开启int8离线量化 -config.enable_mkldnn() # 开启MKLDNN -``` - - - -### PaddlePredictor - -class paddle.fluid.core.PaddlePredictor - -`PaddlePredictor`是运行预测的引擎,由`paddle.fluid.core.create_paddle_predictor(config)`创建,主要提供以下方法 - -* `run`: 输入和返回值均为`PaddleTensor`列表类型,功能为运行预测引擎,返回预测结果 - -#### 代码示例 - -``` python -# 设置完AnalysisConfig后创建预测引擎PaddlePredictor -predictor = create_paddle_predictor(config) - -# 设置输入 -x = numpy.array([1, 2, 3], dtype="int64") -x_t = fluid.core.PaddleTensor(x) - -y = numpy.array([4], dtype = "int64") -y_t = fluid.core.PaddleTensor(y) - -# 运行预测引擎得到结果,返回值是一个PaddleTensor的列表 -results = predictor.run([x_t, y_t]) - -# 获得预测结果,并应用到自己的应用中 +config.enable_mkldnn() # 开启MKLDNN ``` -### 使用ZeroCopyTensor管理输入/输出 +### Predictor -`ZeroCopyTensor`是`AnalysisPredictor`的一种输入/输出数据结构,与`PaddleTensor`等同。`ZeroCopyTensor`相比于`PaddleTensor`,可以避免预测时候准备输入以及获取输出时多余的数据拷贝,提高预测性能。 +class paddle.inference.Predictor -注意: 需要注意的是,使用`ZeroCopyTensor`,务必在创建`config`时设置`config.switch_use_feed_fetch_ops(False)`用于显式地在模型运行的时候删去`feed`和`fetch`ops,不会影响模型的效果,但是能提升性能。 - -``` python -# 创建predictor -predictor = create_paddle_predictor(config) - -# 获取输入的名称 -input_names = predictor.get_input_names() -input_tensor = predictor.get_input_tensor(input_names[0]) +`Predictor`是运行预测的引擎,由`paddle.inference.create_predictor(config)`创建,主要提供以下方法 -# 设置输入 -fake_input = numpy.random.randn(1, 3, 318, 318).astype("float32") -input_tensor.copy_from_cpu(fake_input) - -# 运行predictor -predictor.zero_copy_run() - -# 获取输出 -output_names = predictor.get_output_names() -output_tensor = predictor.get_output_tensor(output_names[0]) -output_data = output_tensor.copy_to_cpu() # numpy.ndarray类型 -``` - -### AnalysisPredictor - -class paddle.fluid.core.AnalysisPredictor - -`AnalysisPredictor`是运行预测的引擎,继承于`PaddlePredictor`,同样是由`paddle.fluid.core.create_paddle_predictor(config)`创建,主要提供以下方法 - -* `zero_copy_run()`: 运行预测引擎,返回预测结果 +* `run()`: 运行预测引擎,返回预测结果 * `get_input_names()`: 获取输入的名称 -* `get_input_tensor(input_name: str)`: 根据输入的名称获取对应的`ZeroCopyTensor` +* `get_input_handle(input_name: str)`: 根据输入的名称获取对应的`Tensor` * `get_output_names()`: 获取输出的名称 -* `get_output_tensor(output_name: str)`: 根据输出的名称获取对应的`ZeroCopyTensor` +* `get_output_handle(output_name: str)`: 根据输出的名称获取对应的`Tensor` #### 代码示例 ``` python # 设置完AnalysisConfig后创建预测引擎PaddlePredictor -predictor = create_paddle_predictor(config) +predictor = create_predictor(config) # 获取输入的名称 input_names = predictor.get_input_names() -input_tensor = predictor.get_input_tensor(input_names[0]) +input_handle = predictor.get_input_handle(input_names[0]) # 设置输入 fake_input = numpy.random.randn(1, 3, 318, 318).astype("float32") -input_tensor.reshape([1, 3, 318, 318]) -input_tensor.copy_from_cpu(fake_input) +input_handle.reshape([1, 3, 318, 318]) +input_handle.copy_from_cpu(fake_input) # 运行predictor -predictor.zero_copy_run() +predictor.run() # 获取输出 output_names = predictor.get_output_names() -output_tensor = predictor.get_output_tensor(output_names[0]) +output_handle = predictor.get_output_handle(output_names[0]) ``` -## 支持方法列表 -* PaddleTensor - * `as_ndarray() -> numpy.ndarray` -* ZeroCopyTensor - * `copy_from_cpu(input: numpy.ndarray) -> None` - * `copy_to_cpu() -> numpy.ndarray` - * `reshape(input: numpy.ndarray|List[int]) -> None` - * `shape() -> List[int]` - * `set_lod(input: numpy.ndarray|List[List[int]]) -> None` - * `lod() -> List[List[int]]` - * `type() -> PaddleDType` -* AnalysisConfig - * `set_model(model_dir: str) -> None` - * `set_model(prog_file: str, params_file: str) -> None` - * `model_dir() -> str` - * `prog_file() -> str` - * `params_file() -> str` - * `enable_use_gpu(memory_pool_init_size_mb: int, device_id: int) -> None` - * `gpu_device_id() -> int` - * `switch_ir_optim(x: bool = True) -> None` - * `enable_tensorrt_engine(workspace_size: int = 1 << 20, - max_batch_size: int, - min_subgraph_size: int, - precision_mode: AnalysisConfig.precision, - use_static: bool, - use_calib_mode: bool) -> None` - * `enable_mkldnn() -> None` - * `disable_glog_info() -> None` - * `delete_pass(pass_name: str) -> None` -* PaddlePredictor - * `run(input: List[PaddleTensor]) -> List[PaddleTensor]` -* AnalysisPredictor - * `zero_copy_run() -> None` - * `get_input_names() -> List[str]` - * `get_input_tensor(input_name: str) -> ZeroCopyTensor` - * `get_output_names() -> List[str]` - * `get_output_tensor(output_name: str) -> ZeroCopyTensor` -可参考对应的[C++预测接口](https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/fluid/pybind/inference_api.cc),其中定义了每个接口的参数和返回值 ## 完整使用示例 -下面是使用Fluid Python API进行预测的一个完整示例,使用resnet50模型 +下面是使用Paddle Inference Python API进行预测的一个完整示例,使用resnet50模型 下载[resnet50模型](http://paddle-inference-dist.bj.bcebos.com/resnet50_model.tar.gz)并解压,运行如下命令将会调用预测引擎 @@ -237,70 +154,11 @@ python resnet50_infer.py --model_file ./model/model --params_file ./model/params `resnet50_infer.py` 的内容是 -### PaddleTensor的完整使用示例 - ``` python import argparse import numpy as np - -from paddle.fluid.core import PaddleTensor -from paddle.fluid.core import AnalysisConfig -from paddle.fluid.core import create_paddle_predictor - - -def main(): - args = parse_args() - - # 设置AnalysisConfig - config = AnalysisConfig(args.model_file, args.params_file) - config.disable_gpu() - - # 创建PaddlePredictor - predictor = create_paddle_predictor(config) - - # 设置输入,此处以随机输入为例,用户可自行输入真实数据 - inputs = fake_input(args.batch_size) - - # 运行预测引擎 - outputs = predictor.run(inputs) - output_num = 512 - - # 获得输出并解析 - output = outputs[0] - print(output.name) - output_data = output.as_ndarray() #return numpy.ndarray - assert list(output_data.shape) == [args.batch_size, output_num] - for i in range(args.batch_size): - print(np.argmax(output_data[i])) - - -def fake_input(batch_size): - shape = [batch_size, 3, 318, 318] - data = np.random.randn(*shape).astype("float32") - image = PaddleTensor(data) - return [image] - - -def parse_args(): - parser = argparse.ArgumentParser() - parser.add_argument("--model_file", type=str, help="model filename") - parser.add_argument("--params_file", type=str, help="parameter filename") - parser.add_argument("--batch_size", type=int, default=1, help="batch size") - - return parser.parse_args() - - -if __name__ == "__main__": - main() -``` - -### ZeroCopyTensor的完整使用示例 - -``` python -import argparse -import numpy as np -from paddle.fluid.core import AnalysisConfig -from paddle.fluid.core import create_paddle_predictor +from paddle.inference import Config +from paddle.inference import create_predictor def main(): @@ -310,24 +168,24 @@ def main(): config = set_config(args) # 创建PaddlePredictor - predictor = create_paddle_predictor(config) + predictor = create_predictor(config) # 获取输入的名称 input_names = predictor.get_input_names() - input_tensor = predictor.get_input_tensor(input_names[0]) + input_handle = predictor.get_input_handle(input_names[0]) # 设置输入 fake_input = np.random.randn(1, 3, 318, 318).astype("float32") - input_tensor.reshape([1, 3, 318, 318]) - input_tensor.copy_from_cpu(fake_input) + input_handle.reshape([1, 3, 318, 318]) + input_handle.copy_from_cpu(fake_input) # 运行predictor - predictor.zero_copy_run() + predictor.run() # 获取输出 output_names = predictor.get_output_names() - output_tensor = predictor.get_output_tensor(output_names[0]) - output_data = output_tensor.copy_to_cpu() # numpy.ndarray类型 + output_handle = predictor.get_output_handle(output_names[0]) + output_data = output_handle.copy_to_cpu() # numpy.ndarray类型 def parse_args(): @@ -340,7 +198,7 @@ def parse_args(): def set_config(args): - config = AnalysisConfig(args.model_file, args.params_file) + config = Config(args.model_file, args.params_file) config.disable_gpu() config.switch_use_feed_fetch_ops(False) config.switch_specify_input_names(True) @@ -348,5 +206,79 @@ def set_config(args): if __name__ == "__main__": - main() + main() ``` + +## 支持方法列表 + +* Tensor + * `copy_from_cpu(input: numpy.ndarray) -> None` + * `copy_to_cpu() -> numpy.ndarray` + * `reshape(input: numpy.ndarray|List[int]) -> None` + * `shape() -> List[int]` + * `set_lod(input: numpy.ndarray|List[List[int]]) -> None` + * `lod() -> List[List[int]]` + * `type() -> PaddleDType` +* Config + * `set_model(model_dir: str) -> None` + * `set_model(prog_file: str, params_file: str) -> None` + * `set_model_buffer(model: str, model_size: int, param: str, param_size: int) -> None` + * `model_dir() -> str` + * `prog_file() -> str` + * `params_file() -> str` + * `model_from_memory() -> bool` + * `set_cpu_math_library_num_threads(num: int) -> None` + * `enable_use_gpu(memory_pool_init_size_mb: int, device_id: int) -> None` + * `use_gpu() -> bool` + * `gpu_device_id() -> int` + * `switch_ir_optim(x: bool = True) -> None` + * `switch_ir_debug(x: int=True) -> None` + * `ir_optim() -> bool` + * `enable_tensorrt_engine(workspace_size: int = 1 << 20, + max_batch_size: int, + min_subgraph_size: int, + precision_mode: AnalysisConfig.precision, + use_static: bool, + use_calib_mode: bool) -> None` + * `set_trt_dynamic_shape_info(min_input_shape: Dict[str, List[int]]={}, max_input_shape: Dict[str, List[int]]={}, optim_input_shape: Dict[str, List[int]]={}, disable_trt_plugin_fp16: bool=False) -> None` + * `tensorrt_engine_enabled() -> bool` + * `enable_mkldnn() -> None` + * `enable_mkldnn_bfloat16() -> None` + * `mkldnn_enabled() -> bool` + * `set_mkldnn_cache_capacity(capacity: int=0) -> None` + * `set_mkldnn_op(ops: Set[str]) -> None` + * `set_optim_cache_dir(dir: str) -> None` + * `disable_glog_info() -> None` + * `pass_builder() -> paddle::PassStrategy` + * `delete_pass(pass_name: str) -> None` + * `cpu_math_library_num_threads() -> int` + * `disable_gpu() -> None` + * `enable_lite_engine(precision: PrecisionType, zero_copy: bool, passes_filter: List[str]=[], ops_filter: List[str]=[]) -> None` + * `lite_engine_enabled() -> bool` + * `enable_memory_optim() -> None` + * `enable_profile() -> None` + * `enable_quantizer() -> None` + * `quantizer_config() -> paddle::MkldnnQuantizerConfig` + * `fraction_of_gpu_memory_for_pool() -> float` + * `memory_pool_init_size_mb() -> int` + * `glog_info_disabled() -> bool` + * `gpu_device_id() -> int` + * `specify_input_name() -> bool` + * `switch_specify_input_names(x: bool=True) -> None` + * `specify_input_name(q) -> bool` + * `switch_use_feed_fetch_ops(x: int=True) -> None` + * `use_feed_fetch_ops_enabled() -> bool` + * `to_native_config() -> paddle.fluid.core_avx.NativeConfig` +* `create_predictor(config: Config) -> Predictor` +* Predictor + * `run() -> None` + * `get_input_names() -> List[str]` + * `get_input_handle(input_name: str) -> Tensor` + * `get_output_names() -> List[str]` + * `get_output_handle(output_name: str) -> Tensor` + * `clear_intermediate_tensor() -> None` + * `clone() -> Predictor` +* PredictorPool + * `retrive(idx: int) -> Predictor` + +可参考对应的[C++预测接口](https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/fluid/pybind/inference_api.cc),其中定义了每个接口的参数和返回值 diff --git a/doc/paddle/advanced_guide/inference_deployment/inference/windows_cpp_inference.md b/doc/paddle/advanced_guide/inference_deployment/inference/windows_cpp_inference.md index 417eaf1e182535b69596876be2ca8cfb3304f6bd..bb05e89fa9d6dfd1e7a5fd038fd1e19835018ac2 100644 --- a/doc/paddle/advanced_guide/inference_deployment/inference/windows_cpp_inference.md +++ b/doc/paddle/advanced_guide/inference_deployment/inference/windows_cpp_inference.md @@ -2,41 +2,41 @@ 安装与编译 Windows 预测库 =========================== -下载安装包与对应的测试环境 +直接下载安装 ------------- -| 版本说明 | 预测库(1.8.3版本) | 编译器 | 构建工具 | cuDNN | CUDA | +| 版本说明 | 预测库(1.8.4版本) |预测库(2.0.0-beta0版本) | 编译器 | 构建工具 | cuDNN | CUDA | |:---------|:-------------------|:-------------------|:----------------|:--------|:-------| -| cpu_avx_mkl | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.3/win-infer/mkl/cpu/fluid_inference_install_dir.zip) | MSVC 2015 update 3| CMake v3.16.0 | -| cpu_avx_openblas | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.3/win-infer/open/cpu/fluid_inference_install_dir.zip) | MSVC 2015 update 3| CMake v3.16.0 | -| cuda9.0_cudnn7_avx_mkl | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.3/win-infer/mkl/post97/fluid_inference_install_dir.zip) | MSVC 2015 update 3 | CMake v3.16.0 | 7.3.1 | 9.0 | -| cuda9.0_cudnn7_avx_openblas | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.3/win-infer/open/post97/fluid_inference_install_dir.zip) | MSVC 2015 update 3 | CMake v3.16.0 | 7.3.1 | 9.0 | -| cuda10.0_cudnn7_avx_mkl | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.3/win-infer/mkl/post107/fluid_inference_install_dir.zip) | MSVC 2015 update 3 | CMake v3.16.0 | 7.4.1 | 10.0 | +| cpu_avx_mkl | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.4/win-infer/mkl/cpu/fluid_inference_install_dir.zip) | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/2.0.0-beta0/win-infer/mkl/cpu/fluid_inference_install_dir.zip) | MSVC 2015 update 3| CMake v3.16.0 | +| cpu_avx_openblas | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.4/win-infer/open/cpu/fluid_inference_install_dir.zip) || MSVC 2015 update 3| CMake v3.16.0 | +| cuda9.0_cudnn7_avx_mkl | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.4/win-infer/mkl/post97/fluid_inference_install_dir.zip) || MSVC 2015 update 3 | CMake v3.16.0 | 7.3.1 | 9.0 | +| cuda9.0_cudnn7_avx_openblas | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.4/win-infer/open/post97/fluid_inference_install_dir.zip) || MSVC 2015 update 3 | CMake v3.16.0 | 7.3.1 | 9.0 | +| cuda10.0_cudnn7_avx_mkl | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.4/win-infer/mkl/post107/fluid_inference_install_dir.zip) | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.3/win-infer/mkl/cpu/fluid_inference_install_dir.zip) | MSVC 2015 update 3 | CMake v3.16.0 | 7.4.1 | 10.0 | ### 硬件环境 测试环境硬件配置: -| CPU | I7-8700K | +| 操作系统 | win10 家庭版本 | |:---------|:-------------------| +| CPU | I7-8700K | | 内存 | 16G | | 硬盘 | 1T hdd + 256G ssd | | 显卡 | GTX1080 8G | -测试环境操作系统使用 win10 家庭版本 -从源码编译预测库 +从源码编译 -------------- 用户也可以从 PaddlePaddle 核心代码编译C++预测库,只需在编译时配制下面这些编译选项: |选项 |说明 | 值 | |:-------------|:-------|:------------| |CMAKE_BUILD_TYPE | 配置生成器上的构建类型,windows预测库目前只支持Release | Release | -|ON_INFER | 是否生成预测库,编译预测库时必须设置为ON | ON | +|ON_INFER | 是否生成预测库,编译预测库时必须设置为ON | ON | |WITH_GPU | 是否支持GPU | ON/OFF | -|WITH_MKL | 是否使用Intel MKL(数学核心库) | ON/OFF | -|WITH_PYTHON | 是否内嵌PYTHON解释器 | OFF(推荐) | -|MSVC_STATIC_CRT|是否使用/MT 模式进行编译,Windows默认使用 /MT 模式进行编译 |ON/OFF| +|WITH_MKL | 是否使用Intel MKL(数学核心库)或者OPENBLAS | ON/OFF | +|WITH_PYTHON | 是否编译Python包 | OFF(推荐) | +|MSVC_STATIC_CRT|是否使用/MT 模式进行编译,默认使用 /MT 模式进行编译 |ON/OFF| |CUDA_TOOKIT_ROOT_DIR|编译GPU预测库时,需设置CUDA的根目录|YOUR_CUDA_PATH| 请按照推荐值设置,以避免链接不必要的库。其它可选编译选项按需进行设定。 @@ -45,46 +45,45 @@ Windows下安装与编译预测库步骤:(在Windows命令提示符下执行以下指令) -1. 将PaddlePaddle的源码clone在当下目录的Paddle文件夹中,并进入Paddle目录: +1. 将PaddlePaddle的源码clone在当下目录的Paddle文件夹中,并进入Paddle目录,创建build目录: ```bash git clone https://github.com/PaddlePaddle/Paddle.git cd Paddle - ``` - -2. 执行cmake: - - 编译CPU预测 - ```bash # 创建并进入build目录 mkdir build cd build + ``` - cmake .. -G "Visual Studio 14 2015" -A x64 -T host=x64 -DCMAKE_BUILD_TYPE=Release -DWITH_MKL=OFF -DWITH_GPU=OFF -DON_INFER=ON -DWITH_PYTHON=OFF +2. 执行cmake: + - 编译CPU预测库 + ```bash + cmake .. -G "Visual Studio 14 2015" -A x64 -T host=x64 -DCMAKE_BUILD_TYPE=Release -DWITH_MKL=ON -DWITH_GPU=OFF -DON_INFER=ON -DWITH_PYTHON=OFF # Windows默认使用 /MT 模式进行编译,如果想使用 /MD 模式,请使用以下命令。如不清楚两者的区别,请使用上面的命令 - cmake .. -G "Visual Studio 14 2015" -A x64 -T host=x64 -DCMAKE_BUILD_TYPE=Release -DWITH_MKL=OFF -DWITH_GPU=OFF -DON_INFER=ON -DWITH_PYTHON=OFF -DMSVC_STATIC_CRT=OFF + cmake .. -G "Visual Studio 14 2015" -A x64 -T host=x64 -DCMAKE_BUILD_TYPE=Release -DWITH_MKL=ON -DWITH_GPU=OFF -DON_INFER=ON -DWITH_PYTHON=OFF -DMSVC_STATIC_CRT=OFF ``` - 编译GPU预测库: ```bash - # -DCUDA_TOOKIT_ROOT_DIR 为cuda根目录,例如-DCUDA_TOOKIT_ROOT_DIR="D:\\cuda" + # -DCUDA_TOOKIT_ROOT_DIR为你所安装的cuda根目录,例如-DCUDA_TOOKIT_ROOT_DIR="C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v10.0" cmake .. -G "Visual Studio 14 2015" -A x64 -T host=x64 -DCMAKE_BUILD_TYPE=Release -DWITH_MKL=ON -DWITH_GPU=ON -DON_INFER=ON -DWITH_PYTHON=OFF -DCUDA_TOOKIT_ROOT_DIR=YOUR_CUDA_PATH ``` 3. 使用Blend for Visual Studio 2015 打开 `paddle.sln` 文件,选择平台为`x64`,配置为`Release`,编译inference_lib_dist项目。 操作方法:在Visual Studio中选择相应模块,右键选择"生成"(或者"build") -编译成功后,使用C++预测库所需的依赖(包括:(1)编译出的PaddlePaddle预测库和头文件;(2)第三方链接库和头文件;(3)版本信息与编译选项信息) -均会存放于`fluid_inference_install_dir`目录中。 - -version.txt 中记录了该预测库的版本信息,包括Git Commit ID、使用OpenBlas或MKL数学库、CUDA/CUDNN版本号,如: +编译成功后,使用C++预测库所需的依赖(包括:1. 编译出的PaddlePaddle预测库和头文件;2. 第三方链接库和头文件;3. 版本信息与编译选项信息)均会存放于`fluid_inference_install_dir`目录中。 +version.txt 中记录了该预测库的版本信息,包括Git Commit ID、使用OpenBlas或MKL数学库、CUDA/CUDNN版本号、C++编译器版本,如: - GIT COMMIT ID: cc9028b90ef50a825a722c55e5fda4b7cd26b0d6 - WITH_MKL: ON - WITH_MKLDNN: ON - WITH_GPU: ON - CUDA version: 8.0 - CUDNN version: v7 - +```text +GIT COMMIT ID: 264e76cae6861ad9b1d4bcd8c3212f7a78c01e4d +WITH_MKL: ON +WITH_MKLDNN: ON +WITH_GPU: ON +CUDA version: 10.0 +CUDNN version: v7.4 +CXX compiler version: 19.0.24215.1 +``` 编译预测demo ------------- @@ -93,14 +92,13 @@ version.txt 中记录了该预测库的版本信息,包括Git Commit ID、使 测试环境硬件配置: -| CPU | I7-8700K | +| 操作系统 | win10 家庭版本 | |:---------|:-------------------| +| CPU | I7-8700K | | 内存 | 16G | | 硬盘 | 1T hdd + 256G ssd | | 显卡 | GTX1080 8G | -测试环境操作系统使用 win10 家庭版本。 - ### 软件要求 **请您严格按照以下步骤进行安装,否则可能会导致安装失败!** diff --git a/doc/paddle/advanced_guide/inference_deployment/inference/windows_cpp_inference_en.md b/doc/paddle/advanced_guide/inference_deployment/inference/windows_cpp_inference_en.md index e25ae184810153421013c60c96c9533b00261ae0..dd5d08900df3c7bce56e94ef64da8eddde7913e7 100644 --- a/doc/paddle/advanced_guide/inference_deployment/inference/windows_cpp_inference_en.md +++ b/doc/paddle/advanced_guide/inference_deployment/inference/windows_cpp_inference_en.md @@ -2,26 +2,27 @@ Install and Compile C++ Inference Library on Windows =========================== -Direct Download and Install +Download and Install directly ------------- -| Version | Inference Libraries(v1.8.3) | Compiler | Build tools | cuDNN | CUDA | +| Version | Inference Libraries(v1.8.4) |Inference Libraries(v2.0.0-beta0)| Compiler | Build tools | cuDNN | CUDA | |:---------|:-------------------|:-------------------|:----------------|:--------|:-------| -| cpu_avx_mkl | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.3/win-infer/mkl/cpu/fluid_inference_install_dir.zip) | MSVC 2015 update 3| CMake v3.16.0 | -| cpu_avx_openblas | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.3/win-infer/open/cpu/fluid_inference_install_dir.zip) | MSVC 2015 update 3| CMake v3.16.0 | -| cuda9.0_cudnn7_avx_mkl | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.3/win-infer/mkl/post97/fluid_inference_install_dir.zip) | MSVC 2015 update 3 | CMake v3.16.0 | 7.3.1 | 9.0 | -| cuda9.0_cudnn7_avx_openblas | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.3/win-infer/open/post97/fluid_inference_install_dir.zip) | MSVC 2015 update 3 | CMake v3.16.0 | 7.3.1 | 9.0 | -| cuda10.0_cudnn7_avx_mkl | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.3/win-infer/mkl/post107/fluid_inference_install_dir.zip) | MSVC 2015 update 3 | CMake v3.16.0 | 7.4.1 | 10.0 | +| cpu_avx_mkl | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.4/win-infer/mkl/cpu/fluid_inference_install_dir.zip) | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/2.0.0-beta0/win-infer/mkl/cpu/fluid_inference_install_dir.zip) | MSVC 2015 update 3| CMake v3.16.0 | +| cpu_avx_openblas | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.4/win-infer/open/cpu/fluid_inference_install_dir.zip) || MSVC 2015 update 3| CMake v3.16.0 | +| cuda9.0_cudnn7_avx_mkl | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.4/win-infer/mkl/post97/fluid_inference_install_dir.zip) || MSVC 2015 update 3 | CMake v3.16.0 | 7.3.1 | 9.0 | +| cuda9.0_cudnn7_avx_openblas | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.4/win-infer/open/post97/fluid_inference_install_dir.zip) || MSVC 2015 update 3 | CMake v3.16.0 | 7.3.1 | 9.0 | +| cuda10.0_cudnn7_avx_mkl | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.4/win-infer/mkl/post107/fluid_inference_install_dir.zip) | [fluid_inference.zip](https://paddle-wheel.bj.bcebos.com/1.8.3/win-infer/mkl/cpu/fluid_inference_install_dir.zip) | MSVC 2015 update 3 | CMake v3.16.0 | 7.4.1 | 10.0 | ### Hardware Environment Hardware Configuration of the experimental environment: -| CPU | I7-8700K | -|:--------------|:-------------------| -| Memory | 16G | -| Hard Disk | 1T hdd + 256G ssd | -| Graphics Card | GTX1080 8G | +|Operating System| win10 family version| +|:---------------|:-------------------| +| CPU | I7-8700K | +| Memory | 16G | +| Hard Disk | 1T hdd + 256G ssd | +| Graphics Card | GTX1080 8G | The operating system is win10 family version in the experimental environment. @@ -36,8 +37,8 @@ Users can also compile C++ inference libraries from the PaddlePaddle core code b |ON_INFER|Whether to generate the inference library. Must be set to ON when compiling the inference library. | ON | |WITH_GPU|Whether to support GPU | ON/OFF | |WITH_MKL|Whether to support MKL | ON/OFF | -|WITH_PYTHON|Whether the PYTHON interpreter is embedded | OFF | -|MSVC_STATIC_CRT|Whether to compile with / MT mode | ON | +|WITH_PYTHON|Whether to generate the Python whl package| OFF | +|MSVC_STATIC_CRT|Whether to compile with /MT mode | ON | |CUDA_TOOKIT_ROOT_DIR | When compiling the GPU inference library, you need to set the CUDA root directory | YOUR_CUDA_PATH | For details on the compilation options, see [the compilation options list](../../../beginners_guide/install/Tables_en.html/#Compile) @@ -54,21 +55,16 @@ For details on the compilation options, see [the compilation options list](../.. - compile CPU inference library ```bash - # create build directory - mkdir build - - # change to the build directory - cd build - cmake .. -G "Visual Studio 14 2015" -A x64 -T host=x64 -DCMAKE_BUILD_TYPE=Release -DWITH_MKL=OFF -DWITH_GPU=OFF -DON_INFER=ON -DWITH_PYTHON=OFF + cmake .. -G "Visual Studio 14 2015" -A x64 -T host=x64 -DCMAKE_BUILD_TYPE=Release -DWITH_MKL=ON -DWITH_GPU=OFF -DON_INFER=ON -DWITH_PYTHON=OFF # use -DWITH_MKL to select math library: Intel MKL or OpenBLAS # By default on Windows we use /MT for C Runtime Library, If you want to use /MD, please use the below command # If you have no ideas the differences between the two, use the above one - cmake .. -G "Visual Studio 14 2015" -A x64 -T host=x64 -DCMAKE_BUILD_TYPE=Release -DWITH_MKL=OFF -DWITH_GPU=OFF -DON_INFER=ON -DWITH_PYTHON=OFF -DMSVC_STATIC_CRT=OFF + cmake .. -G "Visual Studio 14 2015" -A x64 -T host=x64 -DCMAKE_BUILD_TYPE=Release -DWITH_MKL=ON -DWITH_GPU=OFF -DON_INFER=ON -DWITH_PYTHON=OFF -DMSVC_STATIC_CRT=OFF ``` - compile GPU inference library ```bash - # -DCUDA_TOOKIT_ROOT_DIR is cuda root directory, such as -DCUDA_TOOKIT_ROOT_DIR="D:\\cuda" + # -DCUDA_TOOKIT_ROOT_DIR is cuda root directory, such as -DCUDA_TOOKIT_ROOT_DIR="C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v10.0" cmake .. -G "Visual Studio 14 2015" -A x64 -T host=x64 -DCMAKE_BUILD_TYPE=Release -DWITH_MKL=ON -DWITH_GPU=ON -DON_INFER=ON -DWITH_PYTHON=OFF -DCUDA_TOOKIT_ROOT_DIR=YOUR_CUDA_PATH ``` @@ -76,15 +72,18 @@ For details on the compilation options, see [the compilation options list](../.. The inference library will be installed in `fluid_inference_install_dir`. -version.txt constains the detailed configurations about the library, including git commit ID、math library, CUDA, CUDNN versions: +version.txt constains the detailed configurations about the library, including git commit ID、math library, CUDA, CUDNN versions, CXX compiler version: - GIT COMMIT ID: cc9028b90ef50a825a722c55e5fda4b7cd26b0d6 - WITH_MKL: ON - WITH_MKLDNN: ON - WITH_GPU: ON - CUDA version: 8.0 - CUDNN version: v7 +```text +GIT COMMIT ID: 264e76cae6861ad9b1d4bcd8c3212f7a78c01e4d +WITH_MKL: ON +WITH_MKLDNN: ON +WITH_GPU: ON +CUDA version: 10.0 +CUDNN version: v7.4 +CXX compiler version: 19.0.24215.1 +``` Inference Demo Compilation @@ -94,13 +93,12 @@ Inference Demo Compilation Hardware Configuration of the experimental environment: -| CPU | I7-8700K | -|:--------------|:-------------------| -| Memory | 16G | -| Hard Disk | 1T hdd + 256G ssd | -| Graphics Card | GTX1080 8G | - -The operating system is win10 family version in the experimental environment. +|Operating System| win10 family version| +|:---------------|:-------------------| +| CPU | I7-8700K | +| Memory | 16G | +| Hard Disk | 1T hdd + 256G ssd | +| Graphics Card | GTX1080 8G | ### Steps to Configure Environment diff --git a/doc/paddle/api/alias_api_mapping b/doc/paddle/api/alias_api_mapping index 3a43a1cdf51facf13c9a1f8c255d5fd3228bfec4..a29a76ae8f8d09c8519a84fa570b9123f0b18712 100644 --- a/doc/paddle/api/alias_api_mapping +++ b/doc/paddle/api/alias_api_mapping @@ -8,7 +8,7 @@ paddle.nn.functional.common.alpha_dropout paddle.nn.functional.alpha_dropout paddle.nn.functional.activation.log_sigmoid paddle.nn.functional.log_sigmoid paddle.fluid.executor.Executor paddle.static.Executor paddle.nn.functional.pooling.avg_pool2d paddle.nn.functional.avg_pool2d -paddle.fluid.dygraph.checkpoint.load_dygraph paddle.load,paddle.framework.load +paddle.framework.io.load paddle.load,paddle.framework.load paddle.fluid.dygraph.container.Sequential paddle.nn.Sequential paddle.fluid.dygraph.BilinearTensorProduct paddle.nn.BilinearTensorProduct,paddle.nn.layer.BilinearTensorProduct,paddle.nn.layer.common.BilinearTensorProduct paddle.fluid.layers.box_coder paddle.nn.functional.box_coder,paddle.nn.functional.vision.box_coder @@ -251,7 +251,7 @@ paddle.nn.functional.activation.prelu paddle.nn.functional.prelu paddle.tensor.linalg.matmul paddle.matmul,paddle.tensor.matmul paddle.fluid.layers.generate_proposals paddle.nn.functional.generate_proposals,paddle.nn.functional.vision.generate_proposals paddle.nn.layer.loss.SmoothL1Loss paddle.nn.SmoothL1Loss,paddle.nn.layer.SmoothL1Loss -paddle.fluid.dygraph.checkpoint.save_dygraph paddle.save,paddle.framework.save +paddle.framework.io.save paddle.save,paddle.framework.save paddle.fluid.core paddle.framework.core paddle.nn.functional.vision.grid_sample paddle.nn.functional.grid_sample paddle.tensor.random.rand paddle.rand,paddle.tensor.rand @@ -282,7 +282,7 @@ paddle.framework.get_default_dtype paddle.get_default_dtype paddle.fluid.layers.atan paddle.atan,paddle.tensor.atan,paddle.tensor.math.atan paddle.fluid.layers.pad2d paddle.nn.functional.pad2d,paddle.nn.functional.common.pad2d paddle.nn.layer.pooling.MaxPool3d paddle.nn.MaxPool3d,paddle.nn.layer.MaxPool3d -paddle.fluid.io.load paddle.static.load,paddle.tensor.load,paddle.tensor.io.load +paddle.fluid.io.load paddle.static.load paddle.fluid.dygraph.learning_rate_scheduler.ExponentialDecay paddle.ExponentialDecay,paddle.framework.ExponentialDecay paddle.fluid.layers.conv3d paddle.static.nn.conv3d paddle.nn.layer.activation.Softmax paddle.nn.Softmax @@ -447,7 +447,7 @@ paddle.tensor.stat.numel paddle.numel,paddle.tensor.numel paddle.nn.functional.activation.relu6 paddle.nn.functional.relu6 paddle.tensor.math.cumsum paddle.cumsum,paddle.tensor.cumsum paddle.fluid.layers.resize_trilinear paddle.nn.functional.resize_trilinear,paddle.nn.functional.vision.resize_trilinear -paddle.fluid.save paddle.static.save,paddle.tensor.save,paddle.tensor.io.save +paddle.fluid.io.save paddle.static.save paddle.fluid.layers.scale paddle.scale,paddle.tensor.scale,paddle.tensor.math.scale paddle.fluid.framework.default_startup_program paddle.static.default_startup_program paddle.fluid.layers.noam_decay paddle.nn.functional.noam_decay,paddle.nn.functional.learning_rate.noam_decay @@ -561,7 +561,6 @@ paddle.text.datasets.conll05.Conll05st paddle.text.datasets.Conll05st,paddle.tex paddle.text.datasets.imdb.Imdb paddle.text.datasets.Imdb,paddle.text.Imdb paddle.text.datasets.imikolov.Imikolov paddle.text.datasets.Imikolov,paddle.text.Imikolov paddle.text.datasets.movielens.Movielens paddle.text.datasets.Movielens,paddle.text.Movielens -paddle.text.datasets.movie_reviews.MovieReviews paddle.text.datasets.MovieRevie,paddle.text.MovieRevie paddle.text.datasets.uci_housing.UCIHousing paddle.text.datasets.UCIHousing,paddle.text.UCIHousing paddle.text.datasets.wmt14.WMT14 paddle.text.datasets.WMT14,paddle.text.WMT14 paddle.text.datasets.wmt16.WMT16 paddle.text.datasets.WMT16,paddle.text.WMT16 diff --git a/doc/paddle/api/gen_doc.py b/doc/paddle/api/gen_doc.py index 93926d56b5c44548ee03b80413d976c2adb244e5..211c41cdd2f3ee0da45e2ccba28df29a17a465c9 100644 --- a/doc/paddle/api/gen_doc.py +++ b/doc/paddle/api/gen_doc.py @@ -20,6 +20,9 @@ api_set = set() def get_all_api(root_path='paddle'): for filefiner, name, ispkg in pkgutil.walk_packages( path=paddle.__path__, prefix=paddle.__name__ + '.'): + # not show paddle.reader APIs + if name.startswith("paddle.reader"): + continue try: m = eval(name) except AttributeError: diff --git a/doc/paddle/api/not_display_doc_list b/doc/paddle/api/not_display_doc_list index 4b4521eb11f40e60d4185a4f9294cfd7a024177f..cb197d73d13799a86c8a6cee56b74a7c00ef050a 100644 --- a/doc/paddle/api/not_display_doc_list +++ b/doc/paddle/api/not_display_doc_list @@ -1,5 +1,6 @@ paddle.utils paddle.incubate paddle.hapi.progressbar.ProgressBar -paddle.metric.accuracy -paddle.metric.auc +paddle.fluid.contrib +paddle.optimizer._LRScheduler +paddle.fluid.dygraph.dygraph_to_static diff --git a/doc/paddle/api/paddle/dataset/sentiment_cn.rst b/doc/paddle/api/paddle/dataset/sentiment_cn.rst deleted file mode 100644 index d5826830f07689805114028f6b387731e4770be2..0000000000000000000000000000000000000000 --- a/doc/paddle/api/paddle/dataset/sentiment_cn.rst +++ /dev/null @@ -1,28 +0,0 @@ -.. _cn_api_paddle_dataset_sentiment: - -sentiment -------------------------------- - -脚本获取并预处理由NLTK提供的movie_reviews数据集。 - - -.. py:function:: paddle.dataset.sentiment.get_word_dict() - -按照样本中出现的单词的频率对单词进行排序。 - -返回: words_freq_sorted - -.. py:function:: paddle.dataset.sentiment.train() - -默认的训练集reader creator。 - -.. py:function:: paddle.dataset.sentiment.test() - -默认的测试集reader creator。 - -.. py:function:: paddle.dataset.sentiment.convert(path) - -将数据集转换为recordio格式。 - - - diff --git a/doc/paddle/api/paddle/distributed/fleet/DistributedStrategy_cn.rst b/doc/paddle/api/paddle/distributed/fleet/DistributedStrategy_cn.rst index 0092fb5b1cdbb0c5cc32d41e491b118cbb63657d..1d37cbe322b2b3a25c9d0755f578733f69df265c 100755 --- a/doc/paddle/api/paddle/distributed/fleet/DistributedStrategy_cn.rst +++ b/doc/paddle/api/paddle/distributed/fleet/DistributedStrategy_cn.rst @@ -30,6 +30,35 @@ DistributedStrategy **checkpoints(int):** Recompute策略的检查点,默认为空列表,也即不启用Recompute。 +.. py:attribute:: pipeline + +是否启用Pipeline并行。目前,主要实现单机多GPU间的Pipeline并行和多机间的数据并行。Pipeline信息由用户定义程序中的device_guard确定。 + +**示例代码** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + strategy = fleet.DistributedStrategy() + strategy.pipeline = True + + +.. py:attribute:: pipeline_configs + +设置Pipeline策略的配置。Pipeline策略下,神经网络的不同层在不同的GPU设备。相邻的GPU设备间有用于同步隐层Tensor的队列。Pipeline并行包含多种生产者-消费者形式的硬件对,如GPU-CPU、CPU-GPU、GPU-XPU。加速PIpeline并行的最佳方式是减少Tensor队列中的Tensor大小,这样生产者可以更快的为下游消费者提供数据。 + +**micro_batch (int):** 每个用户定义的mini-batch中包含的更小的micro-batch的数量。 + +**示例代码** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + strategy = fleet.DistributedStrategy() + strategy.pipeline = True + strategy.pipeline_configs = {"micro_batch": 12} + + .. py:attribute:: gradient_merge 梯度累加,是一种大Batch训练的策略。添加这一策略后,模型的参数每过 **k_steps** 步更新一次, @@ -102,3 +131,137 @@ DistributedStrategy **lamb_weight_decay(float):** lars 公式中 weight decay 系数。 默认值是 0.01. **exclude_from_weight_decay(list[str]):** 不应用 weight decay 的 layers 的名字列表,某一layer 的name 如果在列表中,这一layer 的 lamb_weight_decay将被置为 0. 默认值是 None. + +.. py:attribute:: localsgd +是否使用LocalSGD optimizer,默认值:False。更多的细节请参考[Don't Use Large Mini-Batches, Use Local SGD](https://arxiv.org/pdf/1808.07217.pdf) + +**示例代码** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + strategy = fleet.DistributedStrategy() + strategy.localsgd = True # by default this is false + + +.. py:attribute:: localsgd_configs +设置LocalSGD优化器的参数。用户可以配置k_steps和begin_step参数。 + +**示例代码** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + strategy = fleet.DistributedStrategy() + strategy.localsgd = True + strategy.localsgd_configs = {"k_steps": 4, + "begin_step": 30} + +**k_steps(int):** 训练过程中的全局参数更新间隔,默认值1。 + +**begin_step(int):** 指定从第几个step之后进行local SGD算法,默认值1。 + +.. py:attribute:: adaptive_localsgd +是否使用AdaptiveLocalSGD optimizer,默认值:False。更多的细节请参考[Adaptive Communication Strategies to Achieve the Best Error-Runtime Trade-off in Local-Update SGD](https://arxiv.org/pdf/1810.08313.pdf) + +**示例代码** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + strategy = fleet.DistributedStrategy() + strategy.adaptive_localsgd = True # by default this is false + +.. py:attribute:: adaptive_localsgd_configs +设置AdaptiveLocalSGD优化器的参数。用户可以配置init_k_steps和begin_step参数。 + +**示例代码** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + strategy = fleet.DistributedStrategy() + strategy.adaptive_localsgd = True + strategy.adaptive_localsgd_configs = {"init_k_steps": 1, + "begin_step": 30} + +**init_k_steps(int):** 自适应localsgd的初始训练步长。训练后,自适应localsgd方法将自动调整步长。 默认值1。 + +**begin_step(int):** 指定从第几个step之后进行Adaptive LocalSGD算法,默认值1。 + +.. py:attribute:: amp + +是否启用自动混合精度训练。默认值:False + +**示例代码** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + strategy = fleet.DistributedStrategy() + strategy.amp = True # by default this is false + +.. py:attribute:: amp_configs + +设置自动混合精度训练配置。为避免梯度inf或nan,amp会根据梯度值自动调整loss scale值。目前可以通过字典设置以下配置。 + +**init_loss_scaling(float):** 初始loss scaling值。默认值32768。 + +**use_dynamic_loss_scaling(bool):** 是否动态调整loss scale值。默认True。 + +**incr_every_n_steps(int):** 每经过n个连续的正常梯度值才会增大loss scaling值。默认值1000。 + +**decr_every_n_nan_or_inf(int):** 每经过n个连续的无效梯度值(nan或者inf)才会减小loss scaling值。默认值2。 + +**incr_ratio(float):** 每次增大loss scaling值的扩增倍数,其为大于1的浮点数。默认值2.0。 + +**decr_ratio(float):** 每次减小loss scaling值的比例系数,其为小于1的浮点数。默认值0.5。 + +**custom_white_list(list[str]):** 用户自定义OP开启fp16执行的白名单。 + +**custom_black_list(list[str]):** 用户自定义OP禁止fp16执行的黑名单。 + +**示例代码** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + strategy = fleet.DistributedStrategy() + strategy.amp = True + strategy.amp_configs = { + "init_loss_scaling": 32768, + "custom_white_list": ['conv2d']} + +.. py:attribute:: dgc + +是否启用深度梯度压缩训练。更多信息请参考[Deep Gradient Compression](https://arxiv.org/abs/1712.01887)。 默认值:False + +**示例代码** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + strategy = fleet.DistributedStrategy() + strategy.dgc = True # by default this is false + +.. py:attribute:: dgc_configs + +设置dgc策略的配置。目前用户可配置 rampup_begin_step,rampup_step,sparsity参数。 + +**rampup_begin_step(int):** 梯度压缩的起点步。默认值0。 + +**rampup_step(int):** 使用稀疏预热的时间步长。默认值为1。例如:如果稀疏度为[0.75,0.9375,0.984375,0.996,0.999],\ +并且rampup_step为100,则在0~19步时使用0.75,在20~39步时使用0.9375,依此类推。当到达sparsity数组末尾时,此后将会使用0.999。 + +**sparsity(list[float]):** 从梯度张量中获取top个重要元素,比率为(1-当前稀疏度)。默认值为[0.999]。\ +例如:如果sparsity为[0.99, 0.999],则将传输top [1%, 0.1%]的重要元素。 + +**示例代码** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + strategy = fleet.DistributedStrategy() + strategy.dgc = True + strategy.dgc_configs = {"rampup_begin_step": 1252} + diff --git a/doc/paddle/api/paddle/distributed/fleet/Fleet_cn.rst b/doc/paddle/api/paddle/distributed/fleet/Fleet_cn.rst index ab8adc12c2719a1f9fe615f08f77becdf20520ae..228829950bed3ac20c35271bf5bdfc909137fe29 100644 --- a/doc/paddle/api/paddle/distributed/fleet/Fleet_cn.rst +++ b/doc/paddle/api/paddle/distributed/fleet/Fleet_cn.rst @@ -6,80 +6,723 @@ Fleet .. py:class:: paddle.distributed.fleet.Fleet - +Fleet是飞桨分布式训练统一API, 只需要import fleet并简单初始化后即可快速开始使用飞桨大规模分布式训练 .. py:method:: init(role_maker=None, is_collective=False) +使用RoleMaker或其他配置初始化fleet。 + + +参数: + role_maker (RoleMakerBase) 已初始化好的PaddleCloudRoleMaker或UserDefineRoleMaker + is_collective (bool) 在未指定role_maker的情况下,可由init方法自行初始化RoleMaker, is_collective为True则按照collective模式进行创建, is_collective=False则按照ParameterServer模式进行创建 + +返回:None + + +**代码示例1** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + fleet.init() + +**代码示例2** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + fleet.init(is_collective=True) + +**代码示例3** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + role = fleet.PaddleCloudRoleMaker() + fleet.init(role) + .. py:method:: is_first_worker() +返回当前节点是否为第一个`worker`节点, 判断当前worker_index是否为0, 如果为0则返回True,否则返回False + +返回:True/False + + +**代码示例** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + fleet.init() + fleet.is_first_worker() + + .. py:method:: worker_index() +返回当前节点的编号, 每个`worker`节点被分配[0, worker_num-1]内的唯一的编码ID + +返回:int + + +**代码示例** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + fleet.init() + fleet.worker_index() + .. py:method:: worker_num() +返回当前全部训练节点中`workjer`节点的个数 + +返回:int + +**代码示例** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + fleet.init() + fleet.worker_num() + .. py:method:: is_worker() +返回当前节点是否为`worker`节点 + +返回:True/False + +**代码示例** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + fleet.init() + fleet.is_worker() + .. py:method:: worker_endpoints(to_string=False) +返回全部worker节点的ip及端口信息 + +返回:list/string + +**代码示例** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + fleet.init() + fleet.worker_endpoints() + .. py:method:: server_num() +**注意:** + + **该参数只在ParameterServer模式下生效** + + +返回当前全部Server节点的个数 + +返回:int + +**代码示例** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + fleet.init() + fleet.server_num() + .. py:method:: server_index() +**注意:** + + **该参数只在ParameterServer模式下生效** + + +返回当前节点的编号, 每个`server`节点被分配[0, server_num-1]内的唯一的编码ID + +返回:int + + +**代码示例** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + fleet.init() + fleet.server_index() + + .. py:method:: server_endpoints(to_string=False) +**注意:** + + **该参数只在ParameterServer模式下生效** + + +返回全部server节点的ip及端口信息 + +返回:list/string + +**代码示例** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + fleet.init() + fleet.server_endpoints() + + .. py:method:: is_server() +**注意:** + + **该参数只在ParameterServer模式下生效** + + +返回当前节点是否为`server`节点 + +返回:True/False + +**代码示例** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + fleet.init() + fleet.is_server() + + .. py:method:: barrier_worker() +调用集合通信功能,强制要求所有的worker在此处相互等待一次 + +返回:无 + +**代码示例** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + fleet.init() + fleet.barrier_worker() + .. py:method:: init_worker() +worker节点在训练前的初始化, 包括通信模块, 参数同步等 + +返回:无 + +**代码示例** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + fleet.init() + fleet.init_worker() + .. py:method:: init_server(*args, **kwargs) +server节点的初始化, 包括server端参数初始化,模型加载等 + +返回:无 + +**代码示例** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + fleet.init() + fleet.init_server() + .. py:method:: run_server() +server节点的运行, 此命令会将ParameterServer的进程启动并常驻直至训练结束 + +返回:无 + +**代码示例** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + fleet.init() + fleet.init_server() + fleet.run_server() + .. py:method:: stop_worker() +停止当前正在运行的worker节点 + +返回:无 + +**代码示例** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + fleet.init() + fleet.init_worker() + "..." + fleet.stop_worker() + .. py:method:: save_inference_model(executor, dirname, feeded_var_names, target_vars, main_program=None, export_for_deployment=True) +修剪指定的 ``main_program`` 以构建一个专门用于预测的 ``Inference Program`` ( ``Program`` 含义详见 :ref:`api_guide_Program` )。 所得到的 ``Inference Program`` 及其对应的所>有相关参数均被保存到 ``dirname`` 指定的目录中。 + + +参数: + - **executor** (Executor) – 用于保存预测模型的 ``executor`` ,详见 :ref:`api_guide_executor` 。 + - **dirname** (str) – 指定保存预测模型结构和参数的文件目录。 + - **feeded_var_names** (list[str]) – 字符串列表,包含着Inference Program预测时所需提供数据的所有变量名称(即所有输入变量的名称)。 + - **target_vars** (list[Variable]) – ``Variable`` (详见 :ref:`api_guide_Program` )类型列表,包含着模型的所有输出变量。通过这些输出变量即可得到模型的预测结果。 + - **main_program** (Program,可选) – 通过该参数指定的 ``main_program`` 可构建一个专门用于预测的 ``Inference Program`` 。 若为None, 则使用全局默认的 ``_main_program_`` 。>默认值为None。 + - **export_for_deployment** (bool,可选) – 若为True,则 ``main_program`` 指定的Program将被修改为只支持直接预测部署的Program。否则,将存储更多的信息,方便优化和再训练。目前 +只支持设置为True,且默认值为True。 + + +返回:无 + +**代码示例** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + import paddle.fluid as fluid + + fleet.init() + + # build net + # fleet.distributed_optimizer(...) + + exe = fluid.Executor(fluid.CPUPlace()) + fleet.save_inference_model(exe, "dirname", ["feednames1"], [acc, loss], fluid.default_main_program()) + .. py:method:: save_persistables(executor, dirname, main_program=None) +保存全量模型参数 + +参数: + - **executor** (Executor) – 用于保存持久性变量的 ``executor`` ,详见 :ref:`api_guide_executor` 。 + - **dirname** (str) – 用于储存持久性变量的文件目录。 + - **main_program** (Program,可选) – 需要保存持久性变量的Program( ``Program`` 含义详见 :ref:`api_guide_Program` )。如果为None,则使用default_main_Program 。默认值为None>。 + +返回:无 + +**代码示例** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + import paddle.fluid as fluid + + fleet.init() + + # build net + # fleet.distributed_optimizer(...) + + exe = fluid.Executor(fluid.CPUPlace()) + fleet.save_persistables(exe, "dirname", fluid.default_main_program()) + + .. py:method:: distributed_optimizer(optimizer, strategy=None) +基于分布式布式并行策略进行模型的拆分及优化。 + +**代码示例** + +.. code-block:: python + import paddle.distributed.fleet as fleet + role = fleet.role_maker.PaddleCloudRoleMaker(is_collective=True) + fleet.init(role) + strategy = fleet.DistributedStrategy() + optimizer = paddle.optimizer.SGD(learning_rate=0.001) + optimizer = fleet.distributed_optimizer(optimizer, strategy=strategy) + .. py:method:: distributed_model(model) +**注意:** + + **1. 该API只在** `Dygraph <../../user_guides/howto/dygraph/DyGraph.html>`_ **模式下生效** + +返回分布式数据并行模型。 + +参数: + model (Layer) - 用户定义的模型,此处模型是指继承动态图Layer的网络。 + +返回:分布式数据并行模型,该模型同样继承动态图Layer。 + + +**代码示例** + +.. code-block:: python + + + # 这个示例需要由fleetrun启动, 用法为: + # fleetrun --gpus=0,1 example.py + # 脚本example.py中的代码是下面这个示例. + + import paddle + import paddle.nn as nn + from paddle.distributed import fleet + + class LinearNet(nn.Layer): + def __init__(self): + super(LinearNet, self).__init__() + self._linear1 = nn.Linear(10, 10) + self._linear2 = nn.Linear(10, 1) + + def forward(self, x): + return self._linear2(self._linear1(x)) + + # 1. enable dynamic mode + paddle.disable_static() + + # 2. initialize fleet environment + fleet.init(is_collective=True) + + # 3. create layer & optimizer + layer = LinearNet() + loss_fn = nn.MSELoss() + adam = paddle.optimizer.Adam( + learning_rate=0.001, parameters=layer.parameters()) + + # 4. get data_parallel model using fleet + adam = fleet.distributed_optimizer(adam) + dp_layer = fleet.distributed_model(layer) + + # 5. run layer + inputs = paddle.randn([10, 10], 'float32') + outputs = dp_layer(inputs) + labels = paddle.randn([10, 1], 'float32') + loss = loss_fn(outputs, labels) + + print("loss:", loss.numpy()) + + loss = dp_layer.scale_loss(loss) + loss.backward() + dp_layer.apply_collective_grads() + + adam.step() + adam.clear_grad() .. py:method:: state_dict() +**注意:** + + **1. 该API只在** `Dygraph <../../user_guides/howto/dygraph/DyGraph.html>`_ **模式下生效** + +以 ``dict`` 返回当前 ``optimizer`` 使用的所有Tensor 。比如对于Adam优化器,将返回 beta1, beta2, momentum 等Tensor。 + +返回:dict, 当前 ``optimizer`` 使用的所有Tensor。 + + +**代码示例** + +.. code-block:: python + + # 这个示例需要由fleetrun启动, 用法为: + # fleetrun --gpus=0,1 example.py + # 脚本example.py中的代码是下面这个示例. + + import numpy as np + import paddle + from paddle.distributed import fleet + + paddle.disable_static() + fleet.init(is_collective=True) + + value = np.arange(26).reshape(2, 13).astype("float32") + a = paddle.fluid.dygraph.to_variable(value) + + layer = paddle.nn.Linear(13, 5) + adam = paddle.optimizer.Adam(learning_rate=0.01, parameters=layer.parameters()) + + adam = fleet.distributed_optimizer(adam) + dp_layer = fleet.distributed_model(layer) + state_dict = adam.state_dict() + + +.. py:method:: set_state_dict(state_dict) + +**注意:** + + **1. 该API只在** `Dygraph <../../user_guides/howto/dygraph/DyGraph.html>`_ **模式下生效** + +加载 ``optimizer`` 的Tensor字典给当前 ``optimizer`` 。 + +返回:None + + +**代码示例** + +.. code-block:: python + + # 这个示例需要由fleetrun启动, 用法为: + # fleetrun --gpus=0,1 example.py + # 脚本example.py中的代码是下面这个示例. + + import numpy as np + import paddle + from paddle.distributed import fleet + + paddle.disable_static() + fleet.init(is_collective=True) + + value = np.arange(26).reshape(2, 13).astype("float32") + a = paddle.fluid.dygraph.to_variable(value) + + layer = paddle.nn.Linear(13, 5) + adam = paddle.optimizer.Adam(learning_rate=0.01, parameters=layer.parameters()) + + adam = fleet.distributed_optimizer(adam) + dp_layer = fleet.distributed_model(layer) + state_dict = adam.state_dict() + paddle.framework.save(state_dict, "paddle_dy") + para_state_dict, opti_state_dict = paddle.framework.load( "paddle_dy") + adam.set_state_dict(opti_state_dict) + .. py:method:: set_lr(value) +**注意:** + + **1. 该API只在** `Dygraph <../../user_guides/howto/dygraph/DyGraph.html>`_ **模式下生效** + +手动设置当前 ``optimizer`` 的学习率。 + +参数: + value (float) - 需要设置的学习率的值。 + +返回:None + + +**代码示例** + +.. code-block:: python + + # 这个示例需要由fleetrun启动, 用法为: + # fleetrun --gpus=0,1 example.py + # 脚本example.py中的代码是下面这个示例. + + import numpy as np + import paddle + from paddle.distributed import fleet + + paddle.disable_static() + fleet.init(is_collective=True) + + value = np.arange(26).reshape(2, 13).astype("float32") + a = paddle.fluid.dygraph.to_variable(value) + + layer = paddle.nn.Linear(13, 5) + adam = paddle.optimizer.Adam(learning_rate=0.01, parameters=layer.parameters()) + + adam = fleet.distributed_optimizer(adam) + dp_layer = fleet.distributed_model(layer) + + lr_list = [0.2, 0.3, 0.4, 0.5, 0.6] + for i in range(5): + adam.set_lr(lr_list[i]) + lr = adam.get_lr() + print("current lr is {}".format(lr)) + # Print: + # current lr is 0.2 + # current lr is 0.3 + # current lr is 0.4 + # current lr is 0.5 + # current lr is 0.6 + .. py:method:: get_lr() +**注意:** + + **1. 该API只在** `Dygraph <../../user_guides/howto/dygraph/DyGraph.html>`_ **模式下生效** + +获取当前步骤的学习率。 + +返回:float,当前步骤的学习率。 + + + +**代码示例** + +.. code-block:: python + + # 这个示例需要由fleetrun启动, 用法为: + # fleetrun --gpus=0,1 example.py + # 脚本example.py中的代码是下面这个示例. + + import numpy as np + import paddle + from paddle.distributed import fleet + + paddle.disable_static() + fleet.init(is_collective=True) + + value = np.arange(26).reshape(2, 13).astype("float32") + a = paddle.fluid.dygraph.to_variable(value) + + layer = paddle.nn.Linear(13, 5) + adam = paddle.optimizer.Adam(learning_rate=0.01, parameters=layer.parameters()) + + adam = fleet.distributed_optimizer(adam) + dp_layer = fleet.distributed_model(layer) + + lr = adam.get_lr() + print(lr) # 0.01 + .. py:method:: step() +**注意:** + + **1. 该API只在** `Dygraph <../../user_guides/howto/dygraph/DyGraph.html>`_ **模式下生效** + +执行一次优化器并进行参数更新。 + +返回:None。 + + +**代码示例** + +.. code-block:: python + + # 这个示例需要由fleetrun启动, 用法为: + # fleetrun --gpus=0,1 example.py + # 脚本example.py中的代码是下面这个示例. + + import paddle + import paddle.nn as nn + from paddle.distributed import fleet + + class LinearNet(nn.Layer): + def __init__(self): + super(LinearNet, self).__init__() + self._linear1 = nn.Linear(10, 10) + self._linear2 = nn.Linear(10, 1) + + def forward(self, x): + return self._linear2(self._linear1(x)) + + # 1. enable dynamic mode + paddle.disable_static() + + # 2. initialize fleet environment + fleet.init(is_collective=True) + + # 3. create layer & optimizer + layer = LinearNet() + loss_fn = nn.MSELoss() + adam = paddle.optimizer.Adam( + learning_rate=0.001, parameters=layer.parameters()) + + # 4. get data_parallel model using fleet + adam = fleet.distributed_optimizer(adam) + dp_layer = fleet.distributed_model(layer) + + # 5. run layer + inputs = paddle.randn([10, 10], 'float32') + outputs = dp_layer(inputs) + labels = paddle.randn([10, 1], 'float32') + loss = loss_fn(outputs, labels) + + print("loss:", loss.numpy()) + + loss = dp_layer.scale_loss(loss) + loss.backward() + dp_layer.apply_collective_grads() + + adam.step() + adam.clear_grad() + .. py:method:: clear_grad() +**注意:** + + **1. 该API只在** `Dygraph <../../user_guides/howto/dygraph/DyGraph.html>`_ **模式下生效** + + +清除需要优化的参数的梯度。 + +返回:None。 + + +**代码示例** + +.. code-block:: python + + # 这个示例需要由fleetrun启动, 用法为: + # fleetrun --gpus=0,1 example.py + # 脚本example.py中的代码是下面这个示例. + + import paddle + import paddle.nn as nn + from paddle.distributed import fleet + + class LinearNet(nn.Layer): + def __init__(self): + super(LinearNet, self).__init__() + self._linear1 = nn.Linear(10, 10) + self._linear2 = nn.Linear(10, 1) + + def forward(self, x): + return self._linear2(self._linear1(x)) + + # 1. enable dynamic mode + paddle.disable_static() + + # 2. initialize fleet environment + fleet.init(is_collective=True) + + # 3. create layer & optimizer + layer = LinearNet() + loss_fn = nn.MSELoss() + adam = paddle.optimizer.Adam( + learning_rate=0.001, parameters=layer.parameters()) + + # 4. get data_parallel model using fleet + adam = fleet.distributed_optimizer(adam) + dp_layer = fleet.distributed_model(layer) + + # 5. run layer + inputs = paddle.randn([10, 10], 'float32') + outputs = dp_layer(inputs) + labels = paddle.randn([10, 1], 'float32') + loss = loss_fn(outputs, labels) + + print("loss:", loss.numpy()) + + loss = dp_layer.scale_loss(loss) + loss.backward() + dp_layer.apply_collective_grads() + + adam.step() + adam.clear_grad() + .. py:method:: minimize(loss, startup_program=None, parameter_list=None, no_grad_set=None) diff --git a/doc/paddle/api/paddle/distributed/fleet/PaddleCloudRoleMaker_cn.rst b/doc/paddle/api/paddle/distributed/fleet/PaddleCloudRoleMaker_cn.rst index b2c01b050b419377771e1fd3f4a6e0526745311d..809e1c2c303cb3e74a1a64cea871efe21273c727 100644 --- a/doc/paddle/api/paddle/distributed/fleet/PaddleCloudRoleMaker_cn.rst +++ b/doc/paddle/api/paddle/distributed/fleet/PaddleCloudRoleMaker_cn.rst @@ -5,6 +5,41 @@ PaddleCloudRoleMaker .. py:class:: paddle.distributed.fleet.PaddleCloudRoleMaker +PaddleCloudRoleMaker是基于从环境变量中获取分布式相关信息进行分布式配置初始化的接口. +它会自动根据用户在环境变量中的配置进行分布式训练环境初始化,目前PaddleCloudRoleMaker支持ParameterServer分布式训练及Collective分布式训练两种模式的初始化。 +**代码示例** + +.. code-block:: python + + import os + import paddle.distributed.fleet as fleet + + os.environ["PADDLE_PSERVER_NUMS"] = "2" + os.environ["PADDLE_TRAINERS_NUM"] = "2" + + os.environ["POD_IP"] = "127.0.0.1" + os.environ["PADDLE_PORT"] = "36001" + os.environ["TRAINING_ROLE"] = "PSERVER" + os.environ["PADDLE_PSERVERS_IP_PORT_LIST"] = \ + "127.0.0.1:36001,127.0.0.2:36001" + + os.environ["PADDLE_TRAINER_ID"] = "0" + + fleet.PaddleCloudRoleMaker(is_collective=False) + +.. py:method:: to_string() +将当前环境变量以字符串的形式输出 + +返回: string + + +**代码示例**: + +.. code-block:: python + + import paddle.distributed.fleet as fleet + role = fleet.PaddleCloudRoleMaker(is_collective=False) + role.to_string() diff --git a/doc/paddle/api/paddle/distributed/fleet/UserDefinedRoleMaker_cn.rst b/doc/paddle/api/paddle/distributed/fleet/UserDefinedRoleMaker_cn.rst index aee570bc51c9a41cf2b3ff6d47b6cd582913871d..6e6a9402f9b3127ed3135b0b08ed7c13261be28c 100644 --- a/doc/paddle/api/paddle/distributed/fleet/UserDefinedRoleMaker_cn.rst +++ b/doc/paddle/api/paddle/distributed/fleet/UserDefinedRoleMaker_cn.rst @@ -5,6 +5,45 @@ UserDefinedRoleMaker .. py:class:: paddle.distributed.fleet.UserDefinedRoleMaker +UserDefinedRoleMaker是基于从用户自定义的参数中获取分布式相关信息进行分布式配置初始化的接口 +它会自动根据用户的自定义配置进行分布式训练环境初始化,目前UserDefinedRoleMaker支持ParameterServer分布式训练及Collective分布式训练两种模式的初始化。 + + +**代码示例** + +.. code-block:: python + + import paddle.distributed.fleet as fleet + from paddle.distributed.fleet.base.role_maker import Role + + fleet.UserDefinedRoleMaker( + current_id=0, + role=Role.SERVER, + worker_num=2, + server_endpoints=["127.0.0.1:36011", "127.0.0.1:36012"]) + +.. py:method:: to_string() +将当前环境变量以字符串的形式输出 + +返回: string + + +**代码示例**: + +.. code-block:: python + + import paddle.distributed.fleet as fleet + from paddle.distributed.fleet.base.role_maker import Role + + role = fleet.UserDefinedRoleMaker( + current_id=0, + role=Role.SERVER, + worker_num=2, + server_endpoints=["127.0.0.1:36011", "127.0.0.1:36012"]) + + role.to_string() + + diff --git a/doc/paddle/api/paddle/distributed/fleet/UtilBase_cn.rst b/doc/paddle/api/paddle/distributed/fleet/UtilBase_cn.rst index bb873da34f2b91f34472ac31fca3440d8951bbb1..42a2a10fa7a109f6654e50ce7e595fc75c57558a 100644 --- a/doc/paddle/api/paddle/distributed/fleet/UtilBase_cn.rst +++ b/doc/paddle/api/paddle/distributed/fleet/UtilBase_cn.rst @@ -4,7 +4,189 @@ UtilBase ------------------------------- .. py:class:: paddle.distributed.fleet.UtilBase +分布式训练工具类,主要提供集合通信、文件系统操作等接口。 +.. py:method:: all_reduce(input, mode="sum", comm_world="worker") +在指定的通信集合间进行归约操作,并将归约结果返回给集合中每个实例。 +参数: + - **input** (list|numpy.array) – 归约操作的输入。 + - **mode** (str) - 归约操作的模式,包含求和,取最大值和取最小值,默认为求和归约。 + - **comm_world** (str) - 归约操作的通信集合,包含: server集合(“server"),worker集合("worker")及所有节点集合("all"),默认为worker集合。 +返回: + - Numpy.array|None: 一个和 `input` 形状一致的numpy数组或None. +**代码示例**: + +.. code-block:: python + + # Save the following code in `train.py` , and then execute the command `fleetrun --server_num 2 --worker_num 2 train.py` . + from paddle.distributed.fleet.base.util_factory import fleet_util + import paddle.distributed.fleet as fleet + from paddle.distributed.fleet import PaddleCloudRoleMaker + import sys + import numpy as np + + def train(): + role = PaddleCloudRoleMaker( + is_collective=False, + init_gloo=True, + path="./tmp_gloo") + fleet.init(role) + fleet_util._set_role_maker(role) + + if fleet.is_server(): + input = [1, 2] + output = fleet_util.all_reduce(input, "sum", "server") + print(output) + # [2, 4] + elif fleet.is_worker(): + input = np.array([3, 4]) + output = fleet_util.all_reduce(input, "sum", "worker") + print(output) + # [6, 8] + output = fleet_util.all_reduce(input, "sum", "all") + print(output) + # [8, 12] + if __name__ == "__main__": + train() + +.. py:method:: barrier(comm_world="worker") +在指定的通信集合间进行阻塞操作,以实现集合间进度同步。 + +参数: + - **comm_world** (str) - 阻塞操作的通信集合,包含: server集合(“server"),worker集合("worker")及所有节点集合("all"),默认为worker集合。 + +**代码示例**: + +.. code-block:: python + + # Save the following code in `train.py` , and then execute the command `fleetrun --server_num 2 --worker_num 2 train.py` . + + from paddle.distributed.fleet.base.util_factory import fleet_util + import paddle.distributed.fleet as fleet + from paddle.distributed.fleet import PaddleCloudRoleMaker + import sys + + def train(): + role = PaddleCloudRoleMaker( + is_collective=False, + init_gloo=True, + path="./tmp_gloo") + fleet.init(role) + fleet_util._set_role_maker(role) + + if fleet.is_server(): + fleet_util.barrier("server") + print("all server arrive here") + elif fleet.is_worker(): + fleet_util.barrier("worker") + print("all server arrive here") + fleet_util.barrier("all") + print("all servers and workers arrive here") + + if __name__ == "__main__": + train() + +.. py:method:: all_gather(input, comm_world="worker") +在指定的通信集合间进行聚合操作,并将聚合的结果返回给集合中每个实例。 + +参数: + - **input** (int|float) - 聚合操作的输入。 + - **comm_world** (str) - 聚合操作的通信集合,包含: server集合(“server"),worker集合("worker")及所有节点集合("all"),默认为worker集合。 + +返回: + - **output** (List): List格式的聚合结果。 + +**代码示例**: + +.. code-block:: python + + # Save the following code in `train.py` , and then execute the command `fleetrun --server_num 2 --worker_num 2 train.py` . + from paddle.distributed.fleet.base.util_factory import fleet_util + import paddle.distributed.fleet as fleet + from paddle.distributed.fleet import PaddleCloudRoleMaker + import sys + + def train(): + role = PaddleCloudRoleMaker( + is_collective=False, + init_gloo=True, + path="./tmp_gloo") + fleet.init(role) + fleet_util._set_role_maker(role) + + if fleet.is_server(): + input = fleet.server_index() + output = fleet_util.all_gather(input, "server") + print(output) + # output = [0, 1] + elif fleet.is_worker(): + input = fleet.worker_index() + output = fleet_util.all_gather(input, "worker") + # output = [0, 1] + print(output) + output = fleet_util.all_gather(input, "all") + print(output) + # output = [0, 1, 0, 1] + + if __name__ == "__main__": + train() + +.. py:method:: get_file_shard(files) +在数据并行的分布式训练中,获取属于当前训练节点的文件列表。 + +.. code-block:: text + + 示例 1: 原始所有文件列表 `files` = [a, b, c ,d, e],训练节点个数 `trainer_num` = 2,那么属于零号节点的训练文件为[a, b, c],属于1号节点的训练文件为[d, e]。 + 示例 2: 原始所有文件列表 `files` = [a, b],训练节点个数 `trainer_num` = 3,那么属于零号节点的训练文件为[a],属于1号节点的训练文件为[b],属于2号节点的训练文件为[]。 + +参数: + - **files** (List):原始所有文件列表。 + +返回: + - List: 属于当前训练节点的文件列表。 + +**代码示例**: + +.. code-block:: python + + from paddle.distributed.fleet.base.util_factory import fleet_util + import paddle.distributed.fleet.base.role_maker as role_maker + + role = role_maker.UserDefinedRoleMaker( + is_collective=False, + init_gloo=False, + current_id=0, + role=role_maker.Role.WORKER, + worker_endpoints=["127.0.0.1:6003", "127.0.0.1:6004"], + server_endpoints=["127.0.0.1:6001", "127.0.0.1:6002"]) + fleet_util._set_role_maker(role) + files = fleet_util.get_file_shard(["file1", "file2", "file3"]) + # files = ["file1", "file2"] + +.. py:method:: print_on_rank(message, rank_id) + +在编号为 `rank_id` 的节点上打印指定信息。 + +参数: + - **message** (str) – 打印内容。 + - **rank_id** (int) - 节点编号。 + +**代码示例**: + +.. code-block:: python + + from paddle.distributed.fleet.base.util_factory import fleet_util + import paddle.distributed.fleet.base.role_maker as role_maker + + role = role_maker.UserDefinedRoleMaker( + is_collective=False, + init_gloo=False, + current_id=0, + role=role_maker.Role.WORKER, + worker_endpoints=["127.0.0.1:6003", "127.0.0.1:6004"], + server_endpoints=["127.0.0.1:6001", "127.0.0.1:6002"]) + fleet_util._set_role_maker(role) + fleet_util.print_on_rank("I'm worker 0", 0) \ No newline at end of file diff --git a/doc/paddle/api/paddle/distributed/fleet/utils/fs/ExecuteError_cn.rst b/doc/paddle/api/paddle/distributed/fleet/utils/fs/ExecuteError_cn.rst deleted file mode 100644 index 98359d848c42f7855cc2d086187bdfaf5921a23f..0000000000000000000000000000000000000000 --- a/doc/paddle/api/paddle/distributed/fleet/utils/fs/ExecuteError_cn.rst +++ /dev/null @@ -1,10 +0,0 @@ -.. _cn_api_distributed_fleet_utils_fs_ExecuteError: - -ExecuteError -------------------------------- - -.. py:class:: paddle.distributed.fleet.utils.fs.ExecuteError - - - - diff --git a/doc/paddle/api/paddle/distributed/fleet/utils/fs/FSFileExistsError_cn.rst b/doc/paddle/api/paddle/distributed/fleet/utils/fs/FSFileExistsError_cn.rst deleted file mode 100644 index 5081d1ca7d10c319b555db46792455fb65443f0a..0000000000000000000000000000000000000000 --- a/doc/paddle/api/paddle/distributed/fleet/utils/fs/FSFileExistsError_cn.rst +++ /dev/null @@ -1,10 +0,0 @@ -.. _cn_api_distributed_fleet_utils_fs_FSFileExistsError: - -FSFileExistsError -------------------------------- - -.. py:class:: paddle.distributed.fleet.utils.fs.FSFileExistsError - - - - diff --git a/doc/paddle/api/paddle/distributed/fleet/utils/fs/FSFileNotExistsError_cn.rst b/doc/paddle/api/paddle/distributed/fleet/utils/fs/FSFileNotExistsError_cn.rst deleted file mode 100644 index 1bebd7f4487c6e9900b8e90e4c835d166b236724..0000000000000000000000000000000000000000 --- a/doc/paddle/api/paddle/distributed/fleet/utils/fs/FSFileNotExistsError_cn.rst +++ /dev/null @@ -1,10 +0,0 @@ -.. _cn_api_distributed_fleet_utils_fs_FSFileNotExistsError: - -FSFileNotExistsError -------------------------------- - -.. py:class:: paddle.distributed.fleet.utils.fs.FSFileNotExistsError - - - - diff --git a/doc/paddle/api/paddle/distributed/fleet/utils/fs/FSShellCmdAborted_cn.rst b/doc/paddle/api/paddle/distributed/fleet/utils/fs/FSShellCmdAborted_cn.rst deleted file mode 100644 index bf48d0627f84eb83627f7539bac303ccdc3a0eb3..0000000000000000000000000000000000000000 --- a/doc/paddle/api/paddle/distributed/fleet/utils/fs/FSShellCmdAborted_cn.rst +++ /dev/null @@ -1,10 +0,0 @@ -.. _cn_api_distributed_fleet_utils_fs_FSShellCmdAborted: - -FSShellCmdAborted -------------------------------- - -.. py:class:: paddle.distributed.fleet.utils.fs.FSShellCmdAborted - - - - diff --git a/doc/paddle/api/paddle/distributed/fleet/utils/fs/FSTimeOut_cn.rst b/doc/paddle/api/paddle/distributed/fleet/utils/fs/FSTimeOut_cn.rst deleted file mode 100644 index 5de353c06458546b0806df262020b124c8f921d1..0000000000000000000000000000000000000000 --- a/doc/paddle/api/paddle/distributed/fleet/utils/fs/FSTimeOut_cn.rst +++ /dev/null @@ -1,10 +0,0 @@ -.. _cn_api_distributed_fleet_utils_fs_FSTimeOut: - -FSTimeOut -------------------------------- - -.. py:class:: paddle.distributed.fleet.utils.fs.FSTimeOut - - - - diff --git a/doc/paddle/api/paddle/distributed/fleet/utils/fs/FS_cn.rst b/doc/paddle/api/paddle/distributed/fleet/utils/fs/FS_cn.rst deleted file mode 100644 index c290580cef57e9e6d364abd3f4b038d61259d482..0000000000000000000000000000000000000000 --- a/doc/paddle/api/paddle/distributed/fleet/utils/fs/FS_cn.rst +++ /dev/null @@ -1,10 +0,0 @@ -.. _cn_api_distributed_fleet_utils_fs_FS: - -FS -------------------------------- - -.. py:class:: paddle.distributed.fleet.utils.fs.FS - - - - diff --git a/doc/paddle/api/paddle/distributed/fleet/utils/fs/HDFSClient_cn.rst b/doc/paddle/api/paddle/distributed/fleet/utils/fs/HDFSClient_cn.rst index 21fae916cd1360e89ebe94ffc9d1bb53bc79c31b..39d4b0e29105004aabc1f516068654e31e3ddbcd 100644 --- a/doc/paddle/api/paddle/distributed/fleet/utils/fs/HDFSClient_cn.rst +++ b/doc/paddle/api/paddle/distributed/fleet/utils/fs/HDFSClient_cn.rst @@ -3,8 +3,279 @@ HDFSClient ------------------------------- -.. py:class:: paddle.distributed.fleet.utils.fs.HDFSClient +.. py:class:: paddle.distributed.fleet.utils.HDFSClient +一个HADOOP文件系统工具类。 +参数: + - **hadoop_home** (str):HADOOP HOME地址。 + - **configs** (dict): HADOOP文件系统配置。需包含 `fs.default.name` 和 `hadoop.job.ugi` 这两个字段。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import HDFSClient + hadoop_home = "/home/client/hadoop-client/hadoop/" + + configs = { + "fs.default.name": "hdfs://xxx.hadoop.com:54310", + "hadoop.job.ugi": "hello,hello123" + } + + client = HDFSClient(hadoop_home, configs) + client.ls_dir("hdfs:/test_hdfs_client") + +.. py:method:: ls_dir(fs_path) +列出 `fs_path` 路径下所有的文件和子目录。 + +参数: + - **fs_path** (str): HADOOP文件路径。 + +返回: + - Tuple, 一个包含所有子目录和文件名的2-Tuple,格式形如: ([subdirname1, subdirname1, ...], [filename1, filename2, ...])。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import HDFSClient + + hadoop_home = "/home/client/hadoop-client/hadoop/" + configs = { + "fs.default.name": "hdfs://xxx.hadoop.com:54310", + "hadoop.job.ugi": "hello,hello123" + } + + client = HDFSClient(hadoop_home, configs) + subdirs, files = client.ls_dir("hdfs:/test_hdfs_client") + +.. py:method:: mkdirs(fs_path) +创建一个目录。 + +参数: + - **fs_path** (str): HADOOP文件路径。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import HDFSClient + + hadoop_home = "/home/client/hadoop-client/hadoop/" + configs = { + "fs.default.name": "hdfs://xxx.hadoop.com:54310", + "hadoop.job.ugi": "hello,hello123" + } + + client = HDFSClient(hadoop_home, configs) + client.mkdirs("hdfs:/test_hdfs_client") + +.. py:method:: delete(fs_path) +删除HADOOP文件(或目录)。 + +参数: + - **fs_path** (str): HADOOP文件路径。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import HDFSClient + + hadoop_home = "/home/client/hadoop-client/hadoop/" + configs = { + "fs.default.name": "hdfs://xxx.hadoop.com:54310", + "hadoop.job.ugi": "hello,hello123" + } + + client = HDFSClient(hadoop_home, configs) + client.delete("hdfs:/test_hdfs_client") + +.. py:method:: is_file(fs_path) +判断当前路径是否是一个文件。 + +参数: + - **fs_path** (str): HADOOP文件路径。 + +返回: + - Bool:若当前路径存在且是一个文件,返回 `True` ,反之则返回 `False` 。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import HDFSClient + + hadoop_home = "/home/client/hadoop-client/hadoop/" + configs = { + "fs.default.name": "hdfs://xxx.hadoop.com:54310", + "hadoop.job.ugi": "hello,hello123" + } + + client = HDFSClient(hadoop_home, configs) + ret = client.is_file("hdfs:/test_hdfs_client") + +.. py:method:: is_dir(fs_path) +判断当前路径是否是一个目录。 + +参数: + - **fs_path** (str): HADOOP文件路径。 + +返回: + - Bool:若当前路径存在且是一个目录,返回 `True` ,反之则返回 `False` 。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import HDFSClient + + hadoop_home = "/home/client/hadoop-client/hadoop/" + configs = { + "fs.default.name": "hdfs://xxx.hadoop.com:54310", + "hadoop.job.ugi": "hello,hello123" + } + + client = HDFSClient(hadoop_home, configs) + ret = client.is_file("hdfs:/test_hdfs_client") + +.. py:method:: is_exist(fs_path) +判断当前路径是否存在。 + +参数: + - **fs_path** (str): HADOOP文件路径。 + +返回: + - Bool:若当前路径存在返回 `True` ,反之则返回 `False` 。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import HDFSClient + + hadoop_home = "/home/client/hadoop-client/hadoop/" + configs = { + "fs.default.name": "hdfs://xxx.hadoop.com:54310", + "hadoop.job.ugi": "hello,hello123" + } + + client = HDFSClient(hadoop_home, configs) + ret = client.is_exist("hdfs:/test_hdfs_client") + +.. py:method:: upload(local_path, fs_path) +上传本地文件至HADOOP文件系统。 + +参数: + - **local_path** (str): 本地文件路径。 + - **fs_path** (str): HADOOP文件路径。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import HDFSClient + + hadoop_home = "/home/client/hadoop-client/hadoop/" + configs = { + "fs.default.name": "hdfs://xxx.hadoop.com:54310", + "hadoop.job.ugi": "hello,hello123" + } + + client = HDFSClient(hadoop_home, configs) + client.upload("test_hdfs_client", "hdfs:/test_hdfs_client") + +.. py:method:: download(fs_path, local_path) +下载HADOOP文件至本地文件系统。 + +参数: + - **local_path** (str): 本地文件路径。 + - **fs_path** (str): HADOOP文件路径。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import HDFSClient + + hadoop_home = "/home/client/hadoop-client/hadoop/" + configs = { + "fs.default.name": "hdfs://xxx.hadoop.com:54310", + "hadoop.job.ugi": "hello,hello123" + } + + client = HDFSClient(hadoop_home, configs) + client.download("hdfs:/test_hdfs_client", "./") + + +.. py:method:: touch(fs_path, exist_ok=True) +创建一个HADOOP文件。 + +参数: + - **fs_path** (str): HADOOP文件路径。 + - **exist_ok** (bool): 路径已存在时程序是否报错。若 `exist_ok = True`,则直接返回,反之则抛出文件存在的异常,默认不抛出异常。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import HDFSClient + + hadoop_home = "/home/client/hadoop-client/hadoop/" + configs = { + "fs.default.name": "hdfs://xxx.hadoop.com:54310", + "hadoop.job.ugi": "hello,hello123" + } + + client = HDFSClient(hadoop_home, configs) + client.touch("hdfs:/test_hdfs_client") + +.. py:method:: mv(fs_src_path, fs_dst_path, overwrite=False) +HADOOP系统文件移动。 + +参数: + - **fs_src_path** (str): 移动前源文件路径名。 + - **fs_dst_path** (str): 移动后目标文件路径名。 + - **overwrite** (bool): 若目标文件已存在,是否删除进行重写,默认不重写并抛出异常。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import HDFSClient + + hadoop_home = "/home/client/hadoop-client/hadoop/" + configs = { + "fs.default.name": "hdfs://xxx.hadoop.com:54310", + "hadoop.job.ugi": "hello,hello123" + } + + client = HDFSClient(hadoop_home, configs) + client.mv("hdfs:/test_hdfs_client", "hdfs:/test_hdfs_client2") + +.. py:method:: list_dirs(fs_path) +列出HADOOP文件路径下所有的子目录。 + +参数: + - **fs_path** (str): HADOOP文件路径。 + +返回: + - List: 该路径下所有的子目录名。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import HDFSClient + + hadoop_home = "/home/client/hadoop-client/hadoop/" + configs = { + "fs.default.name": "hdfs://xxx.hadoop.com:54310", + "hadoop.job.ugi": "hello,hello123" + } + + client = HDFSClient(hadoop_home, configs) + subdirs = client.list_dirs("hdfs:/test_hdfs_client") diff --git a/doc/paddle/api/paddle/distributed/fleet/utils/fs/LocalFS_cn.rst b/doc/paddle/api/paddle/distributed/fleet/utils/fs/LocalFS_cn.rst index 5169d52c9263a1841c75de1f300d0507b102385c..a63198a3c2533679df877037c01dad630471adf0 100644 --- a/doc/paddle/api/paddle/distributed/fleet/utils/fs/LocalFS_cn.rst +++ b/doc/paddle/api/paddle/distributed/fleet/utils/fs/LocalFS_cn.rst @@ -3,8 +3,196 @@ LocalFS ------------------------------- -.. py:class:: paddle.distributed.fleet.utils.fs.LocalFS +.. py:class:: paddle.distributed.fleet.utils.LocalFS +一个本地文件系统工具类。 +**示例代码**: +.. code-block:: python + from paddle.distributed.fleet.utils import LocalFS + client = LocalFS() + subdirs, files = client.ls_dir("./") +.. py:method:: ls_dir(fs_path) +列出 `fs_path` 路径下所有的文件和子目录。 + +参数: + - **fs_path** (str): 本地文件路径。 + +返回: + - Tuple, 一个包含所有子目录和文件名的2-Tuple,格式形如: ([subdirname1, subdirname1, ...], [filename1, filename2, ...])。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import LocalFS + + client = LocalFS() + subdirs, files = client.ls_dir("./") + +.. py:method:: mkdirs(fs_path) +创建一个本地目录。 + +参数: + - **fs_path** (str): 本地文件路径。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import LocalFS + + client = LocalFS() + client.mkdirs("test_mkdirs") + client.delete("test_mkdirs") + +.. py:method:: rename(fs_src_path, fs_dst_path) +重命名本地文件名。 + +参数: + - **fs_src_path** (str):重命名前原始文件名。 + - **fs_dst_path** (str):新文件名。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import LocalFS + + client = LocalFS() + client.touch("test_rename_src") + print(client.is_exists("test_rename_src")) # True + client.rename("test_rename_src", "test_rename_dst") + print(client.is_exists("test_rename_src")) # False + print(client.is_exists("test_rename_dst")) # True + client.delete("test_rename_dst") + +.. py:method:: delete(fs_path) +删除本地文件(或目录)。 + +参数: + - **fs_path** (str): 本地文件路径。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import LocalFS + + client = LocalFS() + client.mkdirs("test_localFS_mkdirs") + client.delete("test_localFS_mkdirs") + +.. py:method:: is_file(fs_path) +判断当前路径是否是一个文件。 + +参数: + - **fs_path** (str): 本地文件路径。 + +返回: + - Bool:若当前路径存在且是一个文件,返回 `True` ,反之则返回 `False` 。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import LocalFS + + client = LocalFS() + client.touch("test_is_file") + print(client.is_file("test_is_file")) # True + client.delete("test_is_file") + +.. py:method:: is_dir(fs_path) +判断当前路径是否是一个目录。 + +参数: + - **fs_path** (str): 本地文件路径。 + +返回: + - Bool:若当前路径存在且是一个目录,返回 `True` ,反之则返回 `False` 。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import LocalFS + + client = LocalFS() + client.mkdirs("test_is_dir") + print(client.is_dir("test_is_file")) # True + client.delete("test_is_dir") + +.. py:method:: is_exist(fs_path) +判断当前路径是否存在。 + +参数: + - **fs_path** (str): 本地文件路径。 + +返回: + - Bool:若当前路径存在返回 `True` ,反之则返回 `False` 。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import LocalFS + + client = LocalFS() + ret = local_fs.is_exist("test_is_exist") + +.. py:method:: touch(fs_path, exist_ok=True) +创建一个本地文件。 + +参数: + - **fs_path** (str): 本地文件路径。 + - **exist_ok** (bool): 文件路径已存在时程序是否报错。若 `exist_ok = True`,则直接返回,反之则抛出文件存在的异常,默认不抛出异常。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import LocalFS + + client = LocalFS() + client.touch("test_touch") + client.delete("test_touch") + +.. py:method:: mv(src_path, dst_path, overwrite=False) +本地文件移动。 + +参数: + - **src_path** (str): 移动前源文件路径名。 + - **dst_path** (str): 移动后目标文件路径名。 + - **overwrite** (bool): 若目标文件已存在,是否删除进行重写,默认不重写并抛出异常。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import LocalFS + + client = LocalFS() + client.touch("test_mv_src") + client.mv("test_mv_src", "test_mv_dst") + client.delete("test_mv_dst") + +.. py:method:: list_dirs(fs_path) +列出本地路径下所有的子目录。 + +参数: + - **fs_path** (str): 本地文件路径。 + +返回: + - List: 该路径下所有的子目录名。 + +**示例代码**: + +.. code-block:: python + + from paddle.distributed.fleet.utils import LocalFS + + client = LocalFS() + subdirs = client.list_dirs("./") \ No newline at end of file diff --git a/doc/paddle/api/paddle/fluid/dygraph/checkpoint/load_dygraph_cn.rst b/doc/paddle/api/paddle/fluid/dygraph/checkpoint/load_dygraph_cn.rst index a49c06ac7420bedec3fb567ab25e7165951b9f5a..289322788b3a3a2529dba5f52505aee6f0b1e209 100644 --- a/doc/paddle/api/paddle/fluid/dygraph/checkpoint/load_dygraph_cn.rst +++ b/doc/paddle/api/paddle/fluid/dygraph/checkpoint/load_dygraph_cn.rst @@ -4,17 +4,17 @@ load ---- -.. py:function:: paddle.load(model_path, config=None) +.. py:function:: paddle.fluid.dygraph.load_dygraph(model_path, config=None) 该接口用于从磁盘中加载Layer和Optimizer的 ``state_dict`` ,该接口会同时加载 ``model_path + ".pdparams"`` 和 ``model_path + ".pdopt"`` 中的内容。 .. note:: - 由于一些历史原因,如果从 ``paddle.io.save_inference_model`` 的存储结果中载入 ``state_dict`` ,动态图模式下参数的结构性变量名将无法被恢复。并且在将载入的 ``state_dict`` 配置到当前Layer中时,需要配置 ``Layer.set_state_dict`` 的参数 ``use_structured_name=False`` 。 + 如果从 ``paddle.static.save_inference_model`` 的存储结果中载入 ``state_dict`` ,动态图模式下参数的结构性变量名将无法被恢复。并且在将载入的 ``state_dict`` 配置到当前Layer中时,需要配置 ``Layer.set_state_dict`` 的参数 ``use_structured_name=False`` 。 参数: - **model_path** (str) – 保存state_dict的文件前缀。该路径不应该包括后缀 ``.pdparams`` 或 ``.pdopt``。 - - **config** (SaveLoadConfig, 可选) - 用于指定额外配置选项的 :ref:`cn_api_fluid_dygraph_jit_SaveLoadConfig` 对象,这些选项主要是用于兼容 ``paddle.io.save_inference_model`` 存储模型的格式。默认为 ``None``。 + - **config** (SaveLoadConfig, 可选) - 用于指定额外配置选项的 :ref:`cn_api_fluid_dygraph_jit_SaveLoadConfig` 对象,这些选项主要是用于兼容 ``paddle.static.save_inference_model`` 存储模型的格式。默认为 ``None``。 返回: 两个 ``dict`` ,即从文件中恢复的模型参数 ``dict`` 和优化器参数 ``dict``,如果只找到其中一个的存储文件,另一个返回None @@ -29,13 +29,14 @@ load .. code-block:: python import paddle - + import paddle.fluid as fluid + paddle.disable_static() - emb = paddle.nn.Embedding([10, 10]) + emb = paddle.nn.Embedding(10, 10) state_dict = emb.state_dict() - paddle.save(state_dict, "paddle_dy") + fluid.save_dygraph(state_dict, "paddle_dy") scheduler = paddle.optimizer.lr_scheduler.NoamLR( d_model=0.01, warmup_steps=100, verbose=True) @@ -43,9 +44,9 @@ load learning_rate=scheduler, parameters=emb.parameters()) state_dict = adam.state_dict() - paddle.save(state_dict, "paddle_dy") + fluid.save_dygraph(state_dict, "paddle_dy") - para_state_dict, opti_state_dict = paddle.load("paddle_dy") + para_state_dict, opti_state_dict = fluid.load_dygraph("paddle_dy") diff --git a/doc/paddle/api/paddle/fluid/dygraph/jit/SaveLoadConfig_cn.rst b/doc/paddle/api/paddle/fluid/dygraph/jit/SaveLoadConfig_cn.rst index 9cf2165136564c2f81001fa63d2ebfe7b5c4703c..3610fefd1c0b9eabbc35a2c34d98aefd475cddd6 100644 --- a/doc/paddle/api/paddle/fluid/dygraph/jit/SaveLoadConfig_cn.rst +++ b/doc/paddle/api/paddle/fluid/dygraph/jit/SaveLoadConfig_cn.rst @@ -5,7 +5,7 @@ SaveLoadConfig .. py:class:: paddle.SaveLoadConfig() -用于配置接口 :ref:`cn_api_fluid_dygraph_jit_save` 和 :ref:`cn_api_fluid_dygraph_jit_load` 存储载入 :ref:`cn_api_fluid_dygraph_TranslatedLayer` 时的附加选项。 +用于配置接口 ``paddle.jit.save/load`` 和 ``paddle.load`` 存储载入时的附加选项。 **示例代码:** @@ -74,10 +74,10 @@ SaveLoadConfig .. py:attribute:: output_spec -选择保存模型( :ref:`cn_api_fluid_dygraph_TranslatedLayer` )的输出变量,通过指定的这些变量能够使模型仅计算特定的结果。 -默认情况下,原始 :ref:`cn_api_fluid_dygraph_Layer` 的forward方法的所有返回变量都将配置为存储后模型 :ref:`cn_api_fluid_dygraph_TranslatedLayer` 的输出变量。 +选择保存模型( ``paddle.jit.TranslatedLayer`` )的输出变量,通过指定的这些变量能够使模型仅计算特定的结果。 +默认情况下,原始 ``paddle.nn.Layer`` 的forward方法的所有返回变量都将配置为存储后模型 ``paddle.jit.TranslatedLayer`` 的输出变量。 -``output_spec`` 属性类型需要是 ``list[Variable]``。如果输入的 ``output_spec`` 列表不是原始 :ref:`cn_api_fluid_dygraph_Layer` 的forward方法的所有返回变量, +``output_spec`` 属性类型需要是 ``list[Variable]``。如果输入的 ``output_spec`` 列表不是原始 ``paddle.nn.Layer`` 的forward方法的所有返回变量, 将会依据输入的 ``output_spec`` 列表对存储的模型进行裁剪。 .. note:: @@ -132,7 +132,7 @@ SaveLoadConfig .. py:attribute:: model_filename -存储转写 :ref:`cn_api_fluid_dygraph_Layer` 模型结构 ``Program`` 的文件名称。默认文件名为 ``__model__``。 +存储转写 ``paddle.nn.Layer`` 模型结构 ``Program`` 的文件名称。默认文件名为 ``__model__``。 **示例代码** .. code-block:: python @@ -183,7 +183,7 @@ SaveLoadConfig .. py:attribute:: params_filename -存储转写 :ref:`cn_api_fluid_dygraph_Layer` 所有持久参数(包括 ``Parameters`` 和持久的 ``Buffers``)的文件名称。默认文件名称为 ``__variable__``。 +存储转写 ``paddle.nn.Layer`` 所有持久参数(包括 ``Parameters`` 和持久的 ``Buffers``)的文件名称。默认文件名称为 ``__variable__``。 **示例代码** .. code-block:: python @@ -236,10 +236,13 @@ SaveLoadConfig .. py:attribute:: separate_params 配置是否将 :ref:`cn_api_fluid_dygraph_Layer` 的参数存储为分散的文件。 -(这是为了兼容接口 :ref:`cn_api_fluid_io_save_inference_model` 的行为) +(这是为了兼容接口 ``paddle.static.save_inference_model`` 的行为) 如果设置为 ``True`` ,每个参数将会被存储为一个文件,文件名为参数名,同时``SaveLoadConfig.params_filename`` 指定的文件名将不会生效。默认为 ``False``。 +.. note:: + 仅用于 ``paddle.load`` 方法. + **示例代码** .. code-block:: python @@ -273,7 +276,7 @@ SaveLoadConfig adam.clear_grad() model_path = "simplenet.example.model.separate_params" - config = paddle.jit.SaveLoadConfig() + config = paddle.SaveLoadConfig() config.separate_params = True # saving with configs.separate_params @@ -307,11 +310,11 @@ SaveLoadConfig linear = paddle.nn.Linear(5, 1) state_dict = linear.state_dict() - paddle.save(state_dict, "paddle_dy") + paddle.save(state_dict, "paddle_dy.pdparams") - configs = paddle.SaveLoadConfig() - configs.keep_name_table = True - para_state_dict, _ = paddle.load("paddle_dy", configs) + config = paddle.SaveLoadConfig() + config.keep_name_table = True + para_state_dict = paddle.load("paddle_dy.pdparams", config) print(para_state_dict) # the name_table is 'StructuredToParameterName@@' diff --git a/doc/paddle/api/paddle/fluid/dygraph/layers/Layer_cn.rst b/doc/paddle/api/paddle/fluid/dygraph/layers/Layer_cn.rst index ffb30530b8d7a51170deeadb48e843c80ea1c719..ac5d8c3e548c012e6d408467b285db59ed9f7367 100644 --- a/doc/paddle/api/paddle/fluid/dygraph/layers/Layer_cn.rst +++ b/doc/paddle/api/paddle/fluid/dygraph/layers/Layer_cn.rst @@ -410,12 +410,12 @@ buffer是一个非参数类型的变量,不会被优化器更新,但在评 paddle.disable_static() - emb = paddle.nn.Embedding([10, 10]) + emb = paddle.nn.Embedding(10, 10) state_dict = emb.state_dict() - paddle.save(state_dict, "paddle_dy") + paddle.save(state_dict, "paddle_dy.pdparams") - para_state_dict, _ = paddle.load("paddle_dy") + para_state_dict = paddle.load("paddle_dy.pdparams") emb.set_state_dict(para_state_dict) diff --git a/doc/paddle/api/paddle/fluid/io/load_cn.rst b/doc/paddle/api/paddle/fluid/io/load_cn.rst index 36f03340e923d4d2c0689beabb7ccf9215d26377..22cf7593ed23003e1fea5630e5cb802aefaaea6f 100644 --- a/doc/paddle/api/paddle/fluid/io/load_cn.rst +++ b/doc/paddle/api/paddle/fluid/io/load_cn.rst @@ -1,167 +1,58 @@ -.. _cn_api_fluid_dygraph_jit_load: +.. _cn_api_fluid_load: load ------------------ - -.. py:function:: paddle.fluid.dygraph.jit.load(model_path, configs=None) - - -将接口 :ref:`cn_api_fluid_dygraph_jit_save` 或者 :ref:`cn_api_fluid_io_save_inference_model` 存储的模型载入为 :ref:`cn_api_fluid_dygraph_TranslatedLayer` ,用于预测推理或者fine-tune训练。 - -.. note:: - 由于一些历史原因,如果载入的模型是通过 :ref:`cn_api_fluid_io_save_inference_model` 存储的, - 在使用它进行fine-tune训练时会存在一些局限: - 1. 命令式编程模式不支持 ``LoDTensor`` ,所有原先输入变量或者参数依赖于LoD信息的模型暂时无法使用; - 2. 所有存储模型的feed变量都需要被传入 ``Translatedlayer`` 的forward方法; - 3. 原模型变量的 ``stop_gradient`` 信息已丢失且无法准确恢复; - 4. 原模型参数的 ``trainable`` 信息已丢失且无法准确恢复。 - -参数: - - **model_path** (str) - 存储模型的目录。 - - **configs** (SaveLoadConfig, 可选) - 用于指定额外配置选项的 :ref:`cn_api_fluid_dygraph_jit_SaveLoadConfig` 对象。默认为 ``None``。 - -返回:TranslatedLayer - 一个能够执行存储模型的 ``Layer`` 对象。 - -**示例代码** - -1. 载入由接口 :ref:`cn_api_fluid_dygraph_jit_save` 存储的模型进行预测推理及fine-tune训练。 - - .. code-block:: python - - import numpy as np - import paddle.fluid as fluid - from paddle.fluid.dygraph import Linear - from paddle.fluid.dygraph import declarative - BATCH_SIZE = 32 - BATCH_NUM = 20 - def random_batch_reader(): - def _get_random_images_and_labels(image_shape, label_shape): - image = np.random.random(size=image_shape).astype('float32') - label = np.random.random(size=label_shape).astype('int64') - return image, label - def __reader__(): - for _ in range(BATCH_NUM): - batch_image, batch_label = _get_random_images_and_labels( - [BATCH_SIZE, 784], [BATCH_SIZE, 1]) - yield batch_image, batch_label - return __reader__ - class LinearNet(fluid.dygraph.Layer): - def __init__(self, in_size, out_size): - super(LinearNet, self).__init__() - self._linear = Linear(in_size, out_size) - @declarative - def forward(self, x): - return self._linear(x) - # 开启命令式编程模式 - fluid.enable_dygraph() - # 1. 训练存储模型. - # 创建网络 - net = LinearNet(784, 1) - adam = fluid.optimizer.AdamOptimizer(learning_rate=0.1, parameter_list=net.parameters()) - # 创建DataLoader - train_loader = fluid.io.DataLoader.from_generator(capacity=5) - train_loader.set_batch_generator(random_batch_reader()) - # 训练 - for data in train_loader(): - img, label = data - label.stop_gradient = True - cost = net(img) - loss = fluid.layers.cross_entropy(cost, label) - avg_loss = fluid.layers.mean(loss) - avg_loss.backward() - adam.minimize(avg_loss) - net.clear_gradients() - model_path = "linear.example.model" - fluid.dygraph.jit.save( - layer=net, - model_path=model_path, - input_spec=[img]) - # 2. 载入模型 & 预测 - # 载入模型 - infer_net = fluid.dygraph.jit.load(model_path) - # 预测 - x = fluid.dygraph.to_variable(np.random.random((1, 784)).astype('float32')) - pred = infer_net(x) - # 3. 载入模型 & fine-tune训练 - # 载入模型 - train_net = fluid.dygraph.jit.load(model_path) - train_net.train() - adam = fluid.optimizer.AdamOptimizer(learning_rate=0.1, parameter_list=train_net.parameters()) - # 创建DataLoader - train_loader = fluid.io.DataLoader.from_generator(capacity=5) - train_loader.set_batch_generator(random_batch_reader()) - # fine-tune训练 - for data in train_loader(): - img, label = data - label.stop_gradient = True - cost = train_net(img) - loss = fluid.layers.cross_entropy(cost, label) - avg_loss = fluid.layers.mean(loss) - avg_loss.backward() - adam.minimize(avg_loss) - train_net.clear_gradients() - - -2. 载入由接口 :ref:`cn_api_fluid_io_save_inference_model` 存储的模型进行预测推理及fine-tune训练。 - - .. code-block:: python - - import numpy as np - import paddle.fluid as fluid - BATCH_SIZE = 32 - BATCH_NUM = 20 - def random_batch_reader(): - def _get_random_images_and_labels(image_shape, label_shape): - image = np.random.random(size=image_shape).astype('float32') - label = np.random.random(size=label_shape).astype('int64') - return image, label - def __reader__(): - for _ in range(BATCH_NUM): - batch_image, batch_label = _get_random_images_and_labels( - [BATCH_SIZE, 784], [BATCH_SIZE, 1]) - yield batch_image, batch_label - return __reader__ - img = fluid.data(name='img', shape=[None, 784], dtype='float32') - label = fluid.data(name='label', shape=[None, 1], dtype='int64') - pred = fluid.layers.fc(input=img, size=10, act='softmax') - loss = fluid.layers.cross_entropy(input=pred, label=label) - avg_loss = fluid.layers.mean(loss) - optimizer = fluid.optimizer.SGD(learning_rate=0.001) - optimizer.minimize(avg_loss) - place = fluid.CPUPlace() - exe = fluid.Executor(place) - exe.run(fluid.default_startup_program()) - loader = fluid.io.DataLoader.from_generator( - feed_list=[img, label], capacity=5, iterable=True) - loader.set_batch_generator(random_batch_reader(), places=place) - # 1. 训练 & 存储预测模型 - for data in loader(): - exe.run( - fluid.default_main_program(), - feed=data, - fetch_list=[avg_loss]) - model_path = "fc.example.model" - fluid.io.save_inference_model( - model_path, ["img"], [pred], exe) - # 开启命令式编程模式 - fluid.enable_dygraph() - # 2. 载入模型 & 预测 - fc = fluid.dygraph.jit.load(model_path) - x = fluid.dygraph.to_variable(np.random.random((1, 784)).astype('float32')) - pred = fc(x) - # 3. 载入模型 & fine-tune训练 - fc = fluid.dygraph.jit.load(model_path) - fc.train() - sgd = fluid.optimizer.SGD(learning_rate=0.001, - parameter_list=fc.parameters()) - train_loader = fluid.io.DataLoader.from_generator(capacity=5) - train_loader.set_batch_generator( - random_batch_reader(), places=place) - for data in train_loader(): - img, label = data - label.stop_gradient = True - cost = fc(img) - loss = fluid.layers.cross_entropy(cost, label) - avg_loss = fluid.layers.mean(loss) - avg_loss.backward() - sgd.minimize(avg_loss) +------------------------------- + +.. py:function:: paddle.fluid.load(program, model_path, executor=None, var_list=None) + +:api_attr: 声明式编程模式(静态图) + + + +该接口从Program中过滤出参数和优化器信息,然后从文件中获取相应的值。 + +如果Program和加载的文件之间参数的维度或数据类型不匹配,将引发异常。 + +该函数还可以加载用[save_params,save_persistables,save_vars]接口保存的模型文件。 +当[save_params,save_persistables,save_vars]保存的模型格式为单个大文件时,var_list不能为None。 + +参数: + - **program** ( :ref:`cn_api_fluid_Program` ) – 要加载的Program。 + - **model_path** (str) – 保存Program的目录名称+文件前缀。格式为 ``目录名称/文件前缀`` 。 + - **executor** (Executor, 可选) - 当startup program没有运行时,用于初始化参数的Executor。默认值:None。 + - **var_list** (list, 可选) - 指定加载的变量列表,该参数只在加载旧接口[save_params,save_persistables,save_vars]保存的模型文件时使用。当加载的是多个小文件时,变量列表可以是所有加载文件中变量的子集;当加载的单个大文件时,变量列表必须和加载文件中的变量保持一致。 + +返回: 无 + +**代码示例** + +.. code-block:: python + + # example1 + import paddle + import paddle.fluid as fluid + + paddle.enable_static() + + x = fluid.data( name="x", shape=[10, 10], dtype='float32') + y = fluid.layers.fc(x, 10) + z = fluid.layers.fc(y, 10) + place = fluid.CPUPlace() + exe = fluid.Executor(place) + exe.run(fluid.default_startup_program()) + fluid.save(fluid.default_main_program(), "./test_path") + fluid.load(fluid.default_main_program(), "./test_path") + + # example2 + # 注意example1和example2应该分开执行,避免干扰。 + import paddle.fluid as fluid + + x = fluid.data( name="x", shape=[10, 10], dtype='float32') + y = fluid.layers.fc(x, 10) + z = fluid.layers.fc(y, 10) + place = fluid.CPUPlace() + exe = fluid.Executor(place) + exe.run(fluid.default_startup_program()) + fluid.save(fluid.default_main_program(), "./test_path") + fluid.load(fluid.default_main_program(), "./test_path", exe) + diff --git a/doc/paddle/api/paddle/fluid/io/save_cn.rst b/doc/paddle/api/paddle/fluid/io/save_cn.rst new file mode 100644 index 0000000000000000000000000000000000000000..6fe19e65e6acfc4032c7d63e234c9cf644df9490 --- /dev/null +++ b/doc/paddle/api/paddle/fluid/io/save_cn.rst @@ -0,0 +1,54 @@ +.. _cn_api_fluid_save: + +save +------------------------------- + + +.. py:function:: paddle.fluid.save(program, model_path) + +:api_attr: 声明式编程模式(静态图) +:alias_main: paddle.static.save +:alias: paddle.static.save +:old_api: paddle.fluid.save + + + +该接口将传入的参数、优化器信息和网络描述保存到 ``model_path`` 。 + +参数包含所有的可训练 :ref:`cn_api_fluid_Variable` ,将保存到后缀为 ``.pdparams`` 的文件中。 + +优化器信息包含优化器使用的所有变量。对于Adam优化器,包含beta1、beta2、momentum等。 +所有信息将保存到后缀为 ``.pdopt`` 的文件中。(如果优化器没有需要保存的变量(如sgd),则不会生成)。 + +网络描述是程序的描述。它只用于部署。描述将保存到后缀为 ``.pdmodel`` 的文件中。 + +参数: + - **program** ( :ref:`cn_api_fluid_Program` ) – 要保存的Program。 + - **model_path** (str) – 保存program的文件前缀。格式为 ``目录名称/文件前缀``。如果文件前缀为空字符串,会引发异常。 + +返回: 无 + +**代码示例** + +.. code-block:: python + + import paddle + import paddle.fluid as fluid + + paddle.enable_static() + + x = fluid.data(name="x", shape=[10, 10], dtype='float32') + y = fluid.layers.fc(x, 10) + z = fluid.layers.fc(y, 10) + place = fluid.CPUPlace() + exe = fluid.Executor(place) + exe.run(fluid.default_startup_program()) + + fluid.save(fluid.default_main_program(), "./test_path") + + + + + + + diff --git a/doc/paddle/api/paddle/fluid/save_cn.rst b/doc/paddle/api/paddle/fluid/save_cn.rst deleted file mode 100644 index f0276316bacd0d7b7cb7ef6df12b1f9ac08b759f..0000000000000000000000000000000000000000 --- a/doc/paddle/api/paddle/fluid/save_cn.rst +++ /dev/null @@ -1,80 +0,0 @@ -.. _cn_api_fluid_dygraph_jit_save: - -save ------------------ - -.. py:function:: paddle.fluid.dygraph.jit.save(layer, model_path, input_spec=None, configs=None) - -将输入的经过 ``@declarative`` 装饰的 :ref:`cn_api_fluid_dygraph_Layer` 存储为 :ref:`cn_api_fluid_dygraph_TranslatedLayer` 格式的模型, -载入后可用于预测推理或者fine-tune训练。 - -该接口将会将输入 :ref:`cn_api_fluid_dygraph_Layer` 转写后的模型结构 ``Program`` 和所有必要的持久参数变量存储至输入路径 ``model_path`` 中。 - -默认存储的 ``Program`` 文件名为 ``__model__``, 默认存储持久参数变量的文件名为 ``__variables__``, -同时会将变量的一些描述信息存储至文件 ``__variables.info__``,这些额外的信息将在fine-tune训练中使用。 - -存储的模型能够被以下API载入使用: - - :ref:`cn_api_fluid_dygraph_jit_load` - - :ref:`cn_api_fluid_io_load_inference_model` (需要配置参数 ``params_filename='__variables__'`` ) - - 其他预测库API - -参数: - - **layer** (Layer) - 需要存储的 :ref:`cn_api_fluid_dygraph_Layer` 对象。输入的 ``Layer`` 需要经过 ``@declarative`` 装饰。 - - **model_path** (str) - 存储模型的目录。 - - **input_spec** (list[Variable], 可选) - 描述存储模型的输入。此参数是传入当前存储的 ``TranslatedLayer`` forward方法的一个示例输入。如果为 ``None`` ,所有原 ``Layer`` forward方法的输入变量将都会被配置为存储模型的输入变量。默认为 ``None``。 - - **configs** (SaveLoadConfig, 可选) - 用于指定额外配置选项的 :ref:`cn_api_fluid_dygraph_jit_SaveLoadConfig` 对象。默认为 ``None``。 - -返回:无 - -**示例代码** - -.. code-block:: python - - import numpy as np - import paddle.fluid as fluid - from paddle.fluid.dygraph import Linear - from paddle.fluid.dygraph import declarative - BATCH_SIZE = 32 - BATCH_NUM = 20 - def random_batch_reader(): - def _get_random_images_and_labels(image_shape, label_shape): - image = np.random.random(size=image_shape).astype('float32') - label = np.random.random(size=label_shape).astype('int64') - return image, label - def __reader__(): - for _ in range(BATCH_NUM): - batch_image, batch_label = _get_random_images_and_labels( - [BATCH_SIZE, 784], [BATCH_SIZE, 1]) - yield batch_image, batch_label - return __reader__ - class LinearNet(fluid.dygraph.Layer): - def __init__(self, in_size, out_size): - super(LinearNet, self).__init__() - self._linear = Linear(in_size, out_size) - @declarative - def forward(self, x): - return self._linear(x) - # 开启命令式编程模式 - fluid.enable_dygraph() - # 创建网络 - net = LinearNet(784, 1) - adam = fluid.optimizer.AdamOptimizer(learning_rate=0.1, parameter_list=net.parameters()) - # 创建DataLoader - train_loader = fluid.io.DataLoader.from_generator(capacity=5) - train_loader.set_batch_generator(random_batch_reader()) - # 训练 - for data in train_loader(): - img, label = data - label.stop_gradient = True - cost = net(img) - loss = fluid.layers.cross_entropy(cost, label) - avg_loss = fluid.layers.mean(loss) - avg_loss.backward() - adam.minimize(avg_loss) - net.clear_gradients() - # 存储模型 - model_path = "linear.example.model" - fluid.dygraph.jit.save( - layer=net, - model_path=model_path, - input_spec=[img]) diff --git a/doc/paddle/api/paddle/framework/SaveLoadConfig_cn.rst b/doc/paddle/api/paddle/framework/SaveLoadConfig_cn.rst deleted file mode 100644 index cbee1bab234be6f53f83061c52139093513d321b..0000000000000000000000000000000000000000 --- a/doc/paddle/api/paddle/framework/SaveLoadConfig_cn.rst +++ /dev/null @@ -1,273 +0,0 @@ -.. _cn_api_fluid_dygraph_jit_SaveLoadConfig: - -SaveLoadConfig -------------------------------- - -.. py:class:: paddle.fluid.dygraph.jit.SaveLoadConfig() - -用于配置接口 :ref:`cn_api_fluid_dygraph_jit_save` 和 :ref:`cn_api_fluid_dygraph_jit_load` 存储载入 :ref:`cn_api_fluid_dygraph_TranslatedLayer` 时的附加选项。 - -**示例代码:** - - 1. 在存储模型时使用 ``SaveLoadConfig`` - - .. code-block:: python - - import numpy as np - import paddle.fluid as fluid - from paddle.fluid.dygraph import Linear - from paddle.fluid.dygraph import declarative - class SimpleNet(fluid.dygraph.Layer): - def __init__(self, in_size, out_size): - super(SimpleNet, self).__init__() - self._linear = Linear(in_size, out_size) - @declarative - def forward(self, x): - y = self._linear(x) - z = self._linear(y) - return z - # 开启命令式编程模式 - fluid.enable_dygraph() - # 训练模型 - net = SimpleNet(8, 8) - adam = fluid.optimizer.AdamOptimizer(learning_rate=0.1, parameter_list=net.parameters()) - x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) - for i in range(10): - out = net(x) - loss = fluid.layers.mean(out) - loss.backward() - adam.minimize(loss) - net.clear_gradients() - # 在存储模型时使用SaveLoadConfig - model_path = "simplenet.example.model" - configs = fluid.dygraph.jit.SaveLoadConfig() - configs.model_filename = "__simplenet__" - fluid.dygraph.jit.save( - layer=net, - model_path=model_path, - input_spec=[x], - configs=configs) - - 2. 在载入模型时使用 ``SaveLoadConfig`` - - .. code-block:: python - - import numpy as np - import paddle.fluid as fluid - # 开启命令式编程模式 - fluid.enable_dygraph() - # 在载入模型时使用SaveLoadconfig - model_path = "simplenet.example.model" - configs = fluid.dygraph.jit.SaveLoadConfig() - configs.model_filename = "__simplenet__" - infer_net = fluid.dygraph.jit.load(model_path, configs=configs) - # 预测 - x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) - pred = infer_net(x) - -属性 -:::::::::::: - -.. py:attribute:: output_spec - -选择保存模型( :ref:`cn_api_fluid_dygraph_TranslatedLayer` )的输出变量,通过指定的这些变量能够使模型仅计算特定的结果。 -默认情况下,原始 :ref:`cn_api_fluid_dygraph_Layer` 的forward方法的所有返回变量都将配置为存储后模型 :ref:`cn_api_fluid_dygraph_TranslatedLayer` 的输出变量。 - -``output_spec`` 属性类型需要是 ``list[Variable]``。如果输入的 ``output_spec`` 列表不是原始 :ref:`cn_api_fluid_dygraph_Layer` 的forward方法的所有返回变量, -将会依据输入的 ``output_spec`` 列表对存储的模型进行裁剪。 - -.. note:: - ``output_spec`` 属性仅在存储模型时使用。 - -**示例代码:** - .. code-block:: python - - import numpy as np - import paddle.fluid as fluid - from paddle.fluid.dygraph import Linear - from paddle.fluid.dygraph import declarative - class SimpleNet(fluid.dygraph.Layer): - def __init__(self, in_size, out_size): - super(SimpleNet, self).__init__() - self._linear = Linear(in_size, out_size) - @declarative - def forward(self, x): - y = self._linear(x) - z = self._linear(y) - loss = fluid.layers.mean(z) - return z, loss - # 开启命令式编程模式 - fluid.enable_dygraph() - # 训练模型 - net = SimpleNet(8, 8) - adam = fluid.optimizer.AdamOptimizer(learning_rate=0.1, parameter_list=net.parameters()) - x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) - for i in range(10): - out, loss = net(x) - loss.backward() - adam.minimize(loss) - net.clear_gradients() - # 使用SaveLoadconfig.output_spec - model_path = "simplenet.example.model.output_spec" - configs = fluid.dygraph.jit.SaveLoadConfig() - # 仅在存储模型中保留预测结果,丢弃loss - configs.output_spec = [out] - fluid.dygraph.jit.save( - layer=net, - model_path=model_path, - input_spec=[x], - configs=configs) - infer_net = fluid.dygraph.jit.load(model_path, configs=configs) - x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) - # 仅有预测结果输出 - pred = infer_net(x) - - -.. py:attribute:: model_filename - -存储转写 :ref:`cn_api_fluid_dygraph_Layer` 模型结构 ``Program`` 的文件名称。默认文件名为 ``__model__``。 - -**示例代码** - .. code-block:: python - - import numpy as np - import paddle.fluid as fluid - from paddle.fluid.dygraph import Linear - from paddle.fluid.dygraph import declarative - class SimpleNet(fluid.dygraph.Layer): - def __init__(self, in_size, out_size): - super(SimpleNet, self).__init__() - self._linear = Linear(in_size, out_size) - @declarative - def forward(self, x): - y = self._linear(x) - z = self._linear(y) - return z - # 开启命令式编程模式 - fluid.enable_dygraph() - # 训练模型 - net = SimpleNet(8, 8) - adam = fluid.optimizer.AdamOptimizer(learning_rate=0.1, parameter_list=net.parameters()) - x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) - for i in range(10): - out = net(x) - loss = fluid.layers.mean(out) - loss.backward() - adam.minimize(loss) - net.clear_gradients() - model_path = "simplenet.example.model.model_filename" - configs = fluid.dygraph.jit.SaveLoadConfig() - configs.model_filename = "__simplenet__" - # 配置configs.model_filename存储模型 - fluid.dygraph.jit.save( - layer=net, - model_path=model_path, - input_spec=[x], - configs=configs) - # [结果] 存储模型目录文件包括: - # __simplenet__ __variables__ __variables.info__ - # 配置configs.model_filename载入模型 - infer_net = fluid.dygraph.jit.load(model_path, configs=configs) - x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) - pred = infer_net(x) - - -.. py:attribute:: params_filename - -存储转写 :ref:`cn_api_fluid_dygraph_Layer` 所有持久参数(包括 ``Parameters`` 和持久的 ``Buffers``)的文件名称。默认文件名称为 ``__variable__``。 - -**示例代码** - .. code-block:: python - - import numpy as np - import paddle.fluid as fluid - from paddle.fluid.dygraph import Linear - from paddle.fluid.dygraph import declarative - class SimpleNet(fluid.dygraph.Layer): - def __init__(self, in_size, out_size): - super(SimpleNet, self).__init__() - self._linear = Linear(in_size, out_size) - @declarative - def forward(self, x): - y = self._linear(x) - z = self._linear(y) - return z - # 开启命令式编程模式 - fluid.enable_dygraph() - # 训练模型 - net = SimpleNet(8, 8) - adam = fluid.optimizer.AdamOptimizer(learning_rate=0.1, parameter_list=net.parameters()) - x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) - for i in range(10): - out = net(x) - loss = fluid.layers.mean(out) - loss.backward() - adam.minimize(loss) - net.clear_gradients() - model_path = "simplenet.example.model.params_filename" - configs = fluid.dygraph.jit.SaveLoadConfig() - configs.params_filename = "__params__" - # 配置configs.params_filename存储模型 - fluid.dygraph.jit.save( - layer=net, - model_path=model_path, - input_spec=[x], - configs=configs) - # [结果] 存储模型目录文件包括: - # __model__ __params__ __variables.info__ - # 配置configs.params_filename载入模型 - infer_net = fluid.dygraph.jit.load(model_path, configs=configs) - x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) - pred = infer_net(x) - - -.. py:attribute:: separate_params - -配置是否将 :ref:`cn_api_fluid_dygraph_Layer` 的参数存储为分散的文件。 -(这是为了兼容接口 :ref:`cn_api_fluid_io_save_inference_model` 的行为) - -如果设置为 ``True`` ,每个参数将会被存储为一个文件,文件名为参数名,同时``SaveLoadConfig.params_filename`` 指定的文件名将不会生效。默认为 ``False``。 - -**示例代码** - .. code-block:: python - - import numpy as np - import paddle.fluid as fluid - from paddle.fluid.dygraph import Linear - from paddle.fluid.dygraph import declarative - class SimpleNet(fluid.dygraph.Layer): - def __init__(self, in_size, out_size): - super(SimpleNet, self).__init__() - self._linear = Linear(in_size, out_size) - @declarative - def forward(self, x): - y = self._linear(x) - z = self._linear(y) - return z - # 开启命令式编程模式 - fluid.enable_dygraph() - # 训练模型 - net = SimpleNet(8, 8) - adam = fluid.optimizer.AdamOptimizer(learning_rate=0.1, parameter_list=net.parameters()) - x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) - for i in range(10): - out = net(x) - loss = fluid.layers.mean(out) - loss.backward() - adam.minimize(loss) - net.clear_gradients() - model_path = "simplenet.example.model.separate_params" - configs = fluid.dygraph.jit.SaveLoadConfig() - configs.separate_params = True - # 配置configs.separate_params存储模型 - fluid.dygraph.jit.save( - layer=net, - model_path=model_path, - input_spec=[x], - configs=configs) - # [结果] 存储模型目录文件包括: - # linear_0.b_0 linear_0.w_0 __model__ __variables.info__ - # 配置configs.params_filename载入模型 - infer_net = fluid.dygraph.jit.load(model_path, configs=configs) - x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) - pred = infer_net(x) diff --git a/doc/paddle/api/paddle/framework/io/load_cn.rst b/doc/paddle/api/paddle/framework/io/load_cn.rst new file mode 100644 index 0000000000000000000000000000000000000000..e10d2223583c5ceade12055f95c77a27805561c4 --- /dev/null +++ b/doc/paddle/api/paddle/framework/io/load_cn.rst @@ -0,0 +1,46 @@ +.. _cn_api_paddle_framework_io_load: + +load +----- + +.. py:function:: paddle.load(path, config=None) + +从指定路径载入可以在paddle中使用的对象实例。 + +.. note:: + 目前仅支持载入 Layer 或者 Optimizer 的 ``state_dict`` 。 + +.. note:: + ``paddle.load`` 支持从paddle1.x版本中静态图save相关API的存储结果中载入 ``state_dict`` 。 但是从``paddle.static.save_inference_model/paddle.fluid.io.save_params/paddle.fluid.io.save_persistables`` 等API的存储结果中载入 ``state_dict`` 时,动态图模式下参数的结构性变量名将无法被恢复。并且在将载入的 ``state_dict`` 配置到当前Layer中时,需要配置 ``Layer.set_state_dict`` 的参数 ``use_structured_name=False`` 。 + +参数: + - **path** (str) – 载入目标对象实例的路径。通常该路径是目标文件的路径,在兼容载入 ``paddle.jit.save/paddle.static.save_inference_model`` 的存储结果时,该路径是一个目录。 + - **config** (SaveLoadConfig, 可选) - 用于指定额外配置选项的 :ref:`cn_api_fluid_dygraph_jit_SaveLoadConfig` 对象,这些选项主要是用于兼容 ``paddle.jit.save/paddle.static.save_inference_model`` 存储结果的格式。默认为 ``None``。 + + +返回: 一个可以在paddle中使用的对象实例 + +返回类型: Object + +**代码示例** + +.. code-block:: python + + import paddle + + paddle.disable_static() + + emb = paddle.nn.Embedding(10, 10) + layer_state_dict = emb.state_dict() + paddle.save(layer_state_dict, "emb.pdparams") + + scheduler = paddle.optimizer.lr_scheduler.NoamLR( + d_model=0.01, warmup_steps=100, verbose=True) + adam = paddle.optimizer.Adam( + learning_rate=scheduler, + parameters=emb.parameters()) + opt_state_dict = adam.state_dict() + paddle.save(opt_state_dict, "adam.pdopt") + + load_layer_state_dict = paddle.load("emb.pdparams") + load_opt_state_dict = paddle.load("adam.pdopt") diff --git a/doc/paddle/api/paddle/framework/io/save_cn.rst b/doc/paddle/api/paddle/framework/io/save_cn.rst new file mode 100644 index 0000000000000000000000000000000000000000..b3a450f4a348611cca0cd59dad86cbd1917162da --- /dev/null +++ b/doc/paddle/api/paddle/framework/io/save_cn.rst @@ -0,0 +1,37 @@ +.. _cn_api_paddle_framework_io_save: + +save +----- + +.. py:function:: paddle.save(obj, model_path) + +将对象实例obj保存到指定的路径中。 + +.. note:: + 目前仅支持存储 Layer 或者 Optimizer 的 ``state_dict`` 。 + +参数: + - **obj** (Object) – 要保存的对象实例。 + - **path** (str) – 保存对象实例的路径。如果存储到当前路径,输入的path字符串将会作为保存的文件名。 + +返回: 无 + +**代码示例** + +.. code-block:: python + + import paddle + + paddle.disable_static() + + emb = paddle.nn.Embedding(10, 10) + layer_state_dict = emb.state_dict() + paddle.save(layer_state_dict, "emb.pdparams") + + scheduler = paddle.optimizer.lr_scheduler.NoamLR( + d_model=0.01, warmup_steps=100, verbose=True) + adam = paddle.optimizer.Adam( + learning_rate=scheduler, + parameters=emb.parameters()) + opt_state_dict = adam.state_dict() + paddle.save(opt_state_dict, "adam.pdopt") diff --git a/doc/paddle/api/paddle/io/buffered_cn.rst b/doc/paddle/api/paddle/io/buffered_cn.rst index 027c6346f735874d8c9accc38024c09b5940c429..626bda6f19eb4f5a42bff090a7016d8f818ce9f6 100644 --- a/doc/paddle/api/paddle/io/buffered_cn.rst +++ b/doc/paddle/api/paddle/io/buffered_cn.rst @@ -1,9 +1,9 @@ -.. _cn_api_fluid_io_buffered: +.. _cn_api_io_buffered: buffered ------------------------------- -.. py:function:: paddle.fluid.io.buffered(reader, size) +.. py:function:: paddle.io.buffered(reader, size) @@ -14,4 +14,21 @@ buffered - **reader** (callable) – 读取数据的reader - **size** (int) – 最大buffer的大小 -返回:缓存的reader(读取器) \ No newline at end of file +返回:缓存的reader(读取器) + +**代码示例** + +.. code-block:: python + + import paddle + + def reader(): + for i in range(3): + yield i + + # Create a buffered reader, and the buffer size is 2. + buffered_reader = paddle.io.buffered(reader, 2) + + # Output: 0 1 2 + for i in buffered_reader(): + print(i) diff --git a/doc/paddle/api/paddle/io/cache_cn.rst b/doc/paddle/api/paddle/io/cache_cn.rst index e93e4c85d134c0feb2ff813a6127c89816baed76..511bc9219168aeb95b14f5733e4961af401e3cb1 100644 --- a/doc/paddle/api/paddle/io/cache_cn.rst +++ b/doc/paddle/api/paddle/io/cache_cn.rst @@ -1,9 +1,9 @@ -.. _cn_api_fluid_io_cache: +.. _cn_api_io_cache: cache ------------------------------- -.. py:function:: paddle.fluid.io.cache(reader) +.. py:function:: paddle.io.cache(reader) @@ -15,4 +15,21 @@ cache 返回:每次都会从内存中yields数据的一个装饰reader。 -返回类型:生成器 \ No newline at end of file +返回类型:数据保存在内存的reader(读取器) + +**代码示例** + +.. code-block:: python + + import paddle + + def reader(): + for i in range(3): + yield i + + # All data is cached into memory + cached_reader = paddle.io.cache(reader) + + # Output: 0 1 2 + for i in cached_reader(): + print(i) diff --git a/doc/paddle/api/paddle/metric/accuracy_cn.rst b/doc/paddle/api/paddle/metric/accuracy_cn.rst new file mode 100644 index 0000000000000000000000000000000000000000..0ef4deb37b97307a03e3141edf28bdcfb875f7f5 --- /dev/null +++ b/doc/paddle/api/paddle/metric/accuracy_cn.rst @@ -0,0 +1,53 @@ +.. _cn_api_paddle_metric_accuracy: + +accuracy +------------------------------- + +.. py:function:: paddle.metric.accuracy(input, label, k=1, correct=None, total=None) + +accuracy layer。 参考 https://en.wikipedia.org/wiki/Precision_and_recall + +使用输入和标签计算准确率。 如果正确的标签在topk个预测值里,则计算结果加1。注意:输出正确率的类型由input类型决定,input和lable的类型可以不一样。 + +参数 +::::::::: + + - **input** (Tensor|LoDTensor)-数据类型为float32,float64。输入为网络的预测值。shape为 ``[sample_number, class_dim]`` 。 + - **label** (Tensor|LoDTensor)-数据类型为int64,int32。输入为数据集的标签。shape为 ``[sample_number, 1]`` 。 + - **k** (int64|int32) - 取每个类别中k个预测值用于计算。 + - **correct** (int64|int32)-正确预测值的个数。 + - **total** (int64|int32)-总共的预测值。 + +返回 +::::::::: + + ``Tensor``,计算出来的正确率,数据类型为float32的Tensor。 + +代码示例 +::::::::: + +.. code-block:: python + + import paddle.fluid as fluid + import numpy as np + + data = fluid.layers.data(name="input", shape=[-1, 32, 32], dtype="float32") + label = fluid.layers.data(name="label", shape=[-1,1], dtype="int") + fc_out = fluid.layers.fc(input=data, size=10) + predict = fluid.layers.softmax(input=fc_out) + result = fluid.layers.accuracy(input=predict, label=label, k=5) + + place = fluid.CPUPlace() + exe = fluid.Executor(place) + + exe.run(fluid.default_startup_program()) + x = np.random.rand(3, 32, 32).astype("float32") + y = np.array([[1],[0],[1]]) + output= exe.run(feed={"input": x,"label": y}, + fetch_list=[result[0]]) + print(output) + + """ + Output: + [array([0.6666667], dtype=float32)] + """ diff --git a/doc/paddle/api/paddle/metric/auc_cn.rst b/doc/paddle/api/paddle/metric/auc_cn.rst new file mode 100644 index 0000000000000000000000000000000000000000..092380aeb4ea21121cb3ad9563e9b5fb26f9a80b --- /dev/null +++ b/doc/paddle/api/paddle/metric/auc_cn.rst @@ -0,0 +1,71 @@ +.. _cn_api_paddle_metric_auc: + +auc +------------------------------- + +.. py:function:: paddle.metric.auc(input, label, curve='ROC', num_thresholds=200, topk=1, slide_steps=1) + +**Area Under the Curve(AUC) Layer** + +该层根据前向输出和标签计算AUC,在二分类(binary classification)估计中广泛使用。 + +注:如果输入标注包含一种值,只有0或1两种情况,数据类型则强制转换成布尔值。相关定义可以在这里: https://en.wikipedia.org/wiki/Receiver_operating_characteristic#Area_under_the_curve 找到 + +有两种可能的曲线: + +1. ROC:受试者工作特征曲线 + +2. PR:准确率召回率曲线 + +参数: +::::::::: + + - **input** (Tensor|LoDTensor) - 数据类型为float32,float64。浮点二维变量,值的范围为[0,1]。每一行降序排列。该输入为网络预测值的输入。 + - **label** (Tensor|LoDTensor) - 数据类型为int32,int64。二维整型变量,为训练数据的标签。 + - **curve** (str) - 曲线类型,可以为 ``ROC`` 或 ``PR``,默认 ``ROC``。 + - **num_thresholds** (int) - 将roc曲线离散化时使用的临界值数。默认200。 + - **topk** (int) - 取topk的输出值用于计算。 + - **slide_steps** (int) - 当计算batch auc时,不仅用当前步也用于先前步。slide_steps=1,表示用当前步;slide_steps = 3表示用当前步和前两步;slide_steps = 0,则用所有步。 + +返回: +::::::::: + + ``Tensor``, 代表当前AUC的一个元组, 数据类型为float32或float64的Tensor。 + 返回的元组为auc_out, batch_auc_out, [batch_stat_pos, batch_stat_neg, stat_pos, stat_neg]。 + auc_out为准确率的结果。 + batch_auc_out为batch准确率的结果。 + batch_stat_pos为batch计算时label=1的统计值 + batch_stat_neg为batch计算时label=0的统计值 + stat_pos计算时label=1的统计值 + stat_neg为计算时label=0的统计值 + + +代码示例: +::::::::: + +.. code-block:: python + + import paddle.fluid as fluid + import numpy as np + + data = fluid.layers.data(name="input", shape=[-1, 32,32], dtype="float32") + label = fluid.layers.data(name="label", shape=[1], dtype="int") + fc_out = fluid.layers.fc(input=data, size=2) + predict = fluid.layers.softmax(input=fc_out) + result=fluid.layers.auc(input=predict, label=label) + + place = fluid.CPUPlace() + exe = fluid.Executor(place) + + exe.run(fluid.default_startup_program()) + x = np.random.rand(3,32,32).astype("float32") + y = np.array([1,0,1]) + output= exe.run(feed={"input": x,"label": y}, + fetch_list=[result[0]]) + print(output) + """ + output: + [array([0.5])] + """ + + diff --git a/doc/paddle/api/paddle/nn/layer/common/Upsample_cn.rst b/doc/paddle/api/paddle/nn/layer/common/Upsample_cn.rst new file mode 100644 index 0000000000000000000000000000000000000000..3038eb1827983331dfac7c4c7ab43381587e8ae5 --- /dev/null +++ b/doc/paddle/api/paddle/nn/layer/common/Upsample_cn.rst @@ -0,0 +1,194 @@ +.. _cn_api_paddle_nn_UpSample: + +UpSample +------------------------------- + +.. py:class:: paddle.nn.UpSample(out_shape=None, scale=None, resample='BILINEAR', actual_shape=None, align_corners=True, align_mode=1, data_format='NCHW') + +**注意:** 参数 ``actual_shape`` 将被弃用,请使用 ``out_shape`` 替代。 + +该OP用于调整一个batch中图片的大小。 + +输入为3-D Tensor时形状为(num_batches, channels, in_w),输入为4-D Tensor时形状为(num_batches, channels, in_h, in_w)或者(num_batches, in_h, in_w, channels),输入为5-D Tensor时形状为(num_batches, channels, in_d, in_h, in_w)或者(num_batches, in_d, in_h, in_w, channels),并且调整大小只适用于深度,高度和宽度对应的维度。 + +支持的插值方法: + NEAREST:最近邻插值 + + LINEAR:线性插值 + + BILINEAR:双线性插值 + + TRALINEAR:三线性插值 + + BICUBIC:双三次插值 + + +最近邻插值是在输入张量的高度和宽度上进行最近邻插值。 + +线性插值是用一条线连接两个已知量来确定两个已知量之间的一个未知量的值的方法。 + +双线性插值是线性插值的扩展,用于在直线2D网格上插值两个变量(例如,该操作中的H方向和W方向)的函数。 关键思想是首先在一个方向上执行线性插值,然后在另一个方向上再次执行线性插值。 + +三线插值是线性插值的一种扩展,是3参数的插值方程(比如op里的D,H,W方向),在三个方向上进行线性插值。 + +双三次插值是在二维网格上对数据点进行插值的三次插值的扩展,它能创造出比双线性和最近临插值更为光滑的图像边缘。 + +Align_corners和align_mode是可选参数,插值的计算方法可以由它们选择。 + +示例: + +:: + + For scale: + + if align_corners = True && out_size > 1 : + + scale_factor = (in_size-1.0)/(out_size-1.0) + + else: + + scale_factor = float(in_size/out_size) + + + Nearest neighbor interpolation: + + if: + align_corners = False + + input : (N,C,H_in,W_in) + output: (N,C,H_out,W_out) where: + + H_out = \left \lfloor {H_{in} * scale_{}factor}} \right \rfloor + W_out = \left \lfloor {W_{in} * scale_{}factor}} \right \rfloor + + else: + align_corners = True + + input : (N,C,H_in,W_in) + output: (N,C,H_out,W_out) where: + + H_out = round(H_{in} * scale_{factor}) + W_out = round(W_{in} * scale_{factor}) + + Bilinear interpolation: + + if: + align_corners = False , align_mode = 0 + + input : (N,C,H_in,W_in) + output: (N,C,H_out,W_out) where: + + H_out = (H_{in}+0.5) * scale_{factor} - 0.5 + W_out = (W_{in}+0.5) * scale_{factor} - 0.5 + + + else: + + input : (N,C,H_in,W_in) + output: (N,C,H_out,W_out) where: + + H_out = H_{in} * scale_{factor} + W_out = W_{in} * scale_{factor} + + Bicubic interpolation: + + if: + align_corners = False + + input : (N,C,H_in,W_in) + output: (N,C,H_out,W_out) where: + + H_out = (H_{in}+0.5) * scale_{factor} - 0.5 + W_out = (W_{in}+0.5) * scale_{factor} - 0.5 + + else: + + input : (N,C,H_in,W_in) + output: (N,C,H_out,W_out) where: + + H_out = H_{in} * scale_{factor} + W_out = W_{in} * scale_{factor} + + Trilinear interpolation: + + if: + align_corners = False , align_mode = 0 + + input : (N,C,D_in,H_in,W_in) + output: (N,C,D_out,H_out,W_out) where: + + D_out = (D_{in}+0.5) * scale_{factor} - 0.5 + H_out = (H_{in}+0.5) * scale_{factor} - 0.5 + W_out = (W_{in}+0.5) * scale_{factor} - 0.5 + + + else: + + input : (N,C,D_in,H_in,W_in) + output: (N,C,D_out,H_out,W_out) where: + + D_out = D_{in} * scale_{factor} + H_out = H_{in} * scale_{factor} + W_out = W_{in} * scale_{factor} + + +有关最近邻插值的详细信息,请参阅维基百科: +https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation + +有关线性插值的详细信息,请参阅维基百科: +https://en.wikipedia.org/wiki/Linear_interpolation + +有关双线性插值的详细信息,请参阅维基百科: +https://en.wikipedia.org/wiki/Bilinear_interpolation + +有关三线插值的详细信息,请参阅维基百科: +https://en.wikipedia.org/wiki/Trilinear_interpolation + +有关双三次插值的详细信息,请参阅维基百科: +https://en.wikipedia.org/wiki/Bicubic_interpolation + +参数: + - **input** (Variable) - 3-D,4-D或5-D Tensor,数据类型为float32、float64或uint8,其数据格式由参数 ``data_format`` 指定。 + - **out_shape** (list|tuple|Variable|None) - 输出Tensor,输入为3D张量时,形状为为(out_w)的1-D Tensor。输入为4D张量时,形状为为(out_h, out_w)的2-D Tensor。输入为5-D Tensor时,形状为(out_d, out_h, out_w)的3-D Tensor。如果 :code:`out_shape` 是列表,每一个元素可以是整数或者形状为[1]的变量。如果 :code:`out_shape` 是变量,则其维度大小为1。默认值为None。 + - **scale** (float|Variable|None)-输入的高度或宽度的乘数因子 。 out_shape和scale至少要设置一个。out_shape的优先级高于scale。默认值为None。 + - **name** (str|None) - 该参数供开发人员打印调试信息时使用,具体用法请参见 :ref:`api_guide_Name` 。默认值为None。 + - **resample** (str) - 插值方法。支持“线性”,“双线性”,“三线性”,“临近插值”,"双三次"。默认值为双线性插值。 + - **align_corners** (bool)- 一个可选的bool型参数,如果为True,则将输入和输出张量的4个角落像素的中心对齐,并保留角点像素的值。 默认值为True + - **align_mode** (int)- 双线性插值的可选项。 可以是 '0' 代表src_idx = scale *(dst_indx + 0.5)-0.5;如果为'1' ,代表src_idx = scale * dst_index。 + - **data_format** (str,可选)- 指定输入的数据格式,输出的数据格式将与输入保持一致。对于3-D Tensor,支持 NCHW(num_batches, channels, width),对于4-D Tensor,支持 NCHW(num_batches, channels, height, width) 或者 NHWC(num_batches, height, width, channels),对于5-D Tensor,支持 NCDHW(num_batches, channels, depth, height, width)或者 NDHWC(num_batches, depth, height, width, channels),默认值:'NCHW'。 + +返回:3-D Tensor,形状为 (num_batches, channels, out_w) ;4-D Tensor,形状为 (num_batches, channels, out_h, out_w) 或 (num_batches, out_h, out_w, channels);或者5-D Tensor,形状为 (num_batches, channels, out_d, out_h, out_w) 或 (num_batches, out_d, out_h, out_w, channels)。 + +返回类型: 变量(variable) + +抛出异常: + - :code:`TypeError` - out_shape应该是一个列表、元组或变量。 + - :code:`TypeError` - actual_shape应该是变量或None。 + - :code:`ValueError` - image_resize的"resample"只能是"LINEAR"或"BILINEAR"或"TRILINEAR"或"NEAREST"或"BICUBIC"。 + - :code:`ValueError` - out_shape 和 scale 不可同时为 None。 + - :code:`ValueError` - out_shape 的长度必须为2如果输入是4D张量。 + - :code:`ValueError` - out_shape 的长度必须为3如果输入是5D张量。 + - :code:`ValueError` - scale应大于0。 + - :code:`TypeError` - align_corners 应为bool型。 + - :code:`ValueError` - align_mode 只能取 ‘0’ 或 ‘1’。 + - :code:`ValueError` - data_format 只能取 ‘NCW’、 ‘NCHW’、‘NHWC’、‘NCDHW’ 或者 ‘NDHWC’。 + + +**代码示例** + +.. code-block:: python + + import paddle + import numpy as np + + upsample_op = paddle.nn.UpSample(out_shape=[12,12]) + input_data = np.random.rand(2,3,6,10).astype("float32") + + #imperative mode + import paddle.fluid.dygraph as dg + with dg.guard(place) as g: + input = dg.to_variable(input_data) + output = upsample_op(input=input) + + print(output.shape) + # [2L, 3L, 12L, 12L] \ No newline at end of file diff --git a/doc/paddle/api/paddle/reader/ComposeNotAligned_cn.rst b/doc/paddle/api/paddle/reader/ComposeNotAligned_cn.rst deleted file mode 100644 index 1f4a911c5cb8b7dbad64807f81a4114e411ebeab..0000000000000000000000000000000000000000 --- a/doc/paddle/api/paddle/reader/ComposeNotAligned_cn.rst +++ /dev/null @@ -1,14 +0,0 @@ -.. THIS FILE IS GENERATED BY `gen_doc.{py|sh}` - !DO NOT EDIT THIS FILE MANUALLY! - -.. _api_fluid_io_ComposeNotAligned: - -ComposeNotAligned ------------------ - -.. autoclass:: paddle.fluid.io.ComposeNotAligned - :members: - :inherited-members: - :noindex: - -表示一种错误状态,说明调用compose API时, reader的输出数据没有对齐。 diff --git a/doc/paddle/api/paddle/reader/buffered_cn.rst b/doc/paddle/api/paddle/reader/buffered_cn.rst deleted file mode 100644 index 027c6346f735874d8c9accc38024c09b5940c429..0000000000000000000000000000000000000000 --- a/doc/paddle/api/paddle/reader/buffered_cn.rst +++ /dev/null @@ -1,17 +0,0 @@ -.. _cn_api_fluid_io_buffered: - -buffered -------------------------------- - -.. py:function:: paddle.fluid.io.buffered(reader, size) - - - - -创建一个缓存数据读取器,它读取数据并且存储进缓存区,从缓存区读取数据将会加速,只要缓存不是空的。 - -参数: - - **reader** (callable) – 读取数据的reader - - **size** (int) – 最大buffer的大小 - -返回:缓存的reader(读取器) \ No newline at end of file diff --git a/doc/paddle/api/paddle/reader/cache_cn.rst b/doc/paddle/api/paddle/reader/cache_cn.rst deleted file mode 100644 index e93e4c85d134c0feb2ff813a6127c89816baed76..0000000000000000000000000000000000000000 --- a/doc/paddle/api/paddle/reader/cache_cn.rst +++ /dev/null @@ -1,18 +0,0 @@ -.. _cn_api_fluid_io_cache: - -cache -------------------------------- - -.. py:function:: paddle.fluid.io.cache(reader) - - - - -缓存reader数据到内存中,小心此方法可能会花长时间来处理数据,并且会占用大量内存。 ``reader()`` 只能被调用一次。 - -参数: - - **reader** (callable) – 读取数据的reader,每次都会yields数据。 - -返回:每次都会从内存中yields数据的一个装饰reader。 - -返回类型:生成器 \ No newline at end of file diff --git a/doc/paddle/api/paddle/reader/chain_cn.rst b/doc/paddle/api/paddle/reader/chain_cn.rst deleted file mode 100644 index 4a4872d268cc2dfbddad0a6d4720be54e5eb41c9..0000000000000000000000000000000000000000 --- a/doc/paddle/api/paddle/reader/chain_cn.rst +++ /dev/null @@ -1,47 +0,0 @@ -.. _cn_api_fluid_io_chain: - -chain -------------------------------- - -.. py:function:: paddle.fluid.io.chain(*readers) - - - - -该接口将多个数据读取器组成一个数据读取器,它依次返回多个数据读取器的输出数据,同时不改变输出数据原先的格式。 - -举例来说,如果有3个输入读取器且输出分别为[0,0,0]、[10,10,10]和[20,20,20],那么调用该接口产生的新数据读取器的输出为[0,0,0], [10,10,10], [20,20,20]。 - -参数: - - **readers(list)** – 输入的数据读取器。 - -返回: 新的数据读取器。 - -返回类型:callable - -**代码示例** - -.. code-block:: python - - import paddle.fluid as fluid - - def reader_creator_3(start): - def reader(): - for i in range(start, start + 3): - yield [i, i, i] - return reader - - c = fluid.io.chain(reader_creator_3(0), reader_creator_3(10), reader_creator_3(20)) - for e in c(): - print(e) - # 输出结果如下: - # [0, 0, 0] - # [1, 1, 1] - # [2, 2, 2] - # [10, 10, 10] - # [11, 11, 11] - # [12, 12, 12] - # [20, 20, 20] - # [21, 21, 21] - # [22, 22, 22] - diff --git a/doc/paddle/api/paddle/reader/compose_cn.rst b/doc/paddle/api/paddle/reader/compose_cn.rst deleted file mode 100644 index b4393bab5db375413712c27b60fb0699e4d85370..0000000000000000000000000000000000000000 --- a/doc/paddle/api/paddle/reader/compose_cn.rst +++ /dev/null @@ -1,34 +0,0 @@ -.. _cn_api_fluid_io_compose: - -compose -------------------------------- - -.. py:function:: paddle.fluid.io.compose(*readers, **kwargs) - - - - -该接口将多个数据读取器组合为一个数据读取器,返回读取器的输出包含所有输入读取器的输出。 - -例如:如果输入为三个reader,三个reader的输出分别为:(1,2)、3、(4,5),则组合reader的输出为:(1,2,3,4,5)。 - -参数: - - **readers** - 将被组合的多个数据读取器(Reader),数据读取器的定义参见 :ref:`cn_api_paddle_data_reader_reader` 。 - - **check_alignment** (bool) - 可选,指明是否对输入reader进行对齐检查,默认值为True。如果为True,将检查输入reader是否正确对齐。如果为False,将不检查对齐并自动丢弃无法对齐的末尾数据。 - -返回:数据读取器(Reader)。 - -**代码示例**: - -.. code-block:: python - - import paddle.fluid as fluid - def reader_creator_10(dur): - def reader(): - for i in range(10): - yield i - return reader - - reader = fluid.io.compose(reader_creator_10(0), reader_creator_10(0)) - -注意: 运行过程可能会抛出异常 ``ComposeNotAligned`` ,原因是输入的readers数据未对齐。 当check_alignment设置为False时,不会检查并触发该异常。 diff --git a/doc/paddle/api/paddle/reader/firstn_cn.rst b/doc/paddle/api/paddle/reader/firstn_cn.rst deleted file mode 100644 index ba9c1d427ab3ec1946dab0e78f1a2021a712fe94..0000000000000000000000000000000000000000 --- a/doc/paddle/api/paddle/reader/firstn_cn.rst +++ /dev/null @@ -1,30 +0,0 @@ -.. _cn_api_fluid_io_firstn: - -firstn -------------------------------- - -.. py:function:: paddle.fluid.io.firstn(reader, n) - - - - -该接口创建一个数据读取器,它可以返回的最大样本数为n。 - -参数: - - **reader** (callable) – 输入的数据读取器。 - - **n** (int) – 可以返回的最大样本数。 - -返回: 新的的数据读取器。 - -返回类型: callable - -.. code-block:: python - - import paddle.fluid as fluid - def reader(): - for i in range(100): - yield i - firstn_reader = fluid.io.firstn(reader, 5) - for e in firstn_reader(): - print(e) - # 输出结果为:0 1 2 3 4 diff --git a/doc/paddle/api/paddle/reader/map_readers_cn.rst b/doc/paddle/api/paddle/reader/map_readers_cn.rst deleted file mode 100644 index cb50e62839cd523184fef37d4ff9dc625c52fc6b..0000000000000000000000000000000000000000 --- a/doc/paddle/api/paddle/reader/map_readers_cn.rst +++ /dev/null @@ -1,40 +0,0 @@ -.. _cn_api_fluid_io_map_readers: - -map_readers -------------------------------- - -.. py:function:: paddle.fluid.io.map_readers(func, *readers) - - - - -该接口将创建一个数据读取器(Reader),其中 `func` 函数的输出将直接作为新数据读取器的输出, `readers` 的输出将作为函数 `func` 的输入参数。 - -例如:如果输入的 `readers` 为两个输出分别为:2、3 的 `reader` ,输入的 `func` 为乘法函数 `mul(x, y)` ,则得到的新建 `reader` 的输出为:6。 - -参数: - - **func** - 读取数据并返回数据项的函数, `func` 的输出将直接作为新创建的数据读取器的输出。 - - - **readers** - 输入的一个或多个数据读取器(Reader),这些数据读取器的输出数据将作为函数 `func` 的输入参数。数据读取器的定义参见 :ref:`cn_api_paddle_data_reader_reader` 。 - -返回: 新创建的数据读取器(Reader) - -**代码示例**: - -.. code-block:: python - - - import paddle.fluid as fluid - d = {"h": 0, "i": 1} - def func(x): - return d[x] - - def reader(): - yield "h" - yield "i" - - map_reader_result = fluid.io.map_readers(func, reader) - - - - diff --git a/doc/paddle/api/paddle/reader/multiprocess_reader_cn.rst b/doc/paddle/api/paddle/reader/multiprocess_reader_cn.rst deleted file mode 100644 index ab600239eb702ffa2c503f88d5bd9d6ef6bda443..0000000000000000000000000000000000000000 --- a/doc/paddle/api/paddle/reader/multiprocess_reader_cn.rst +++ /dev/null @@ -1,59 +0,0 @@ -.. _cn_api_fluid_io_multiprocess_reader: - -multiprocess_reader -------------------------------- - -.. py:function:: paddle.fluid.io.multiprocess_reader(readers, use_pipe=True, queue_size=1000) - - - - -使用python多进程从 ``readers`` 中读取数据,然后使用 ``multiprocessing.Pipe`` 或 ``multiprocessing.Queue`` 合并所有数据。 ``readers`` 列表中的每个reader会被创建一个独立的进程来调用,reader之间应该相互独立,互不影响,避免出现多进程读取的冲突问题. - -multiprocess.queue需要/dev/shm的rw访问权限,某些平台不支持。 - -参数: - - **readers** (list(generator)|tuple(generator)) - python生成器list, 用来读取数据 - - **use_pipe** (bool,可选) - use_pipe控制multiprocess_reader内部用 ``pipe`` 还是 ``queue`` 来实现进程间通信,默认为 ``True`` 使用 ``pipe`` 进行通信 - - **queue_size** (int,可选) - 如果使用queue来进行进程间通信 (``use_pipe=False``), 则该参数用来设定队列大小 - -返回:使用多进程封装readers之后的reader - -返回类型:python生成器 - - -**代码示例** - -.. code-block:: python - - import paddle.fluid as fluid - from paddle.fluid.io import multiprocess_reader - import numpy as np - - - def fake_reader(start, end): - def __impl__(): - for i in range(start, end): - yield [np.array([1, 2, 3]) * i], - return __impl__ - - - with fluid.program_guard(fluid.Program(), fluid.Program()): - place = fluid.CPUPlace() - image = fluid.layers.data( - name='image', dtype='int64', shape=[3]) - fluid.layers.Print(image) - reader = fluid.io.PyReader( - feed_list=[image], capacity=2) - image_p_1 = image + 1 - decorated_reader = multiprocess_reader( - [fake_reader(1, 5), fake_reader(6, 10)], False) - - reader.decorate_sample_generator(decorated_reader, batch_size=2, places=[place]) - - exe = fluid.Executor(place) - exe.run(fluid.default_startup_program()) - - for data in reader(): - exe.run(feed=data, fetch_list=[image_p_1]) - diff --git a/doc/paddle/api/paddle/reader/xmap_readers_cn.rst b/doc/paddle/api/paddle/reader/xmap_readers_cn.rst deleted file mode 100644 index 5f434ecb9525c4f8dd746319d2b4baace88c89ae..0000000000000000000000000000000000000000 --- a/doc/paddle/api/paddle/reader/xmap_readers_cn.rst +++ /dev/null @@ -1,57 +0,0 @@ -.. _cn_api_fluid_io_xmap_readers: - -xmap_readers -------------------------------- - -.. py:function:: paddle.fluid.io.xmap_readers(mapper, reader, process_num, buffer_size, order=False) - - - - -多线程下,使用自定义映射器 reader 返回样本到输出队列。 - -参数: - - **mapper** (callable): 映射 reader 数据的函数。 - - **reader** (callable): 产生数据的 reader。 - - **process_num** (int): 处理样本的线程数。 - - **buffer_size** (int): 数据缓冲队列大小。 - - **order** (bool): 是否保持原始 reader 数据顺序,默认为 False。 - -返回:一个用户定义的 reader `装饰器 `_ 。 - -返回类型:callable,可调用对象。 - -**代码示例**: - -.. code-block:: python - - import paddle.fluid as fluid - import time - - def reader_creator_10(dur): - def reader(): - for i in range(10): - time.sleep(dur) - yield i - return reader - - def mapper(x): - return (x + 1) - - orders = (True, False) - thread_num = (1, 2, 4, 8, 16) - buffer_size = (1, 2, 4, 8, 16) - for order in orders: - for t_num in thread_num: - for size in buffer_size: - user_reader = fluid.io.xmap_readers(mapper, - reader_creator_10(0), - t_num, size, order) - for n in range(3): - result = list() - for i in user_reader(): - result.append(i) - if not order: - result.sort() - for idx, e in enumerate(result): - assert e == mapper(idx) \ No newline at end of file diff --git a/doc/paddle/api/paddle/io/load_inference_model_cn.rst b/doc/paddle/api/paddle/static/load_inference_model_cn.rst similarity index 98% rename from doc/paddle/api/paddle/io/load_inference_model_cn.rst rename to doc/paddle/api/paddle/static/load_inference_model_cn.rst index 17210d8b2024380bc06223bb99a5d53f9e9c5afe..6cc889f2bd2d87b7e453161695579ffd0f7f0752 100644 --- a/doc/paddle/api/paddle/io/load_inference_model_cn.rst +++ b/doc/paddle/api/paddle/static/load_inference_model_cn.rst @@ -32,9 +32,12 @@ load_inference_model .. code-block:: python + import paddle import paddle.fluid as fluid import numpy as np + paddle.enable_static() + # 构建模型 main_prog = fluid.Program() startup_prog = fluid.Program() diff --git a/doc/paddle/api/paddle/io/load_program_state_cn.rst b/doc/paddle/api/paddle/static/load_program_state_cn.rst similarity index 96% rename from doc/paddle/api/paddle/io/load_program_state_cn.rst rename to doc/paddle/api/paddle/static/load_program_state_cn.rst index 9875b5406c3465e2221b992600d0132b4ed5ee0b..bafcdb38ba150cc38d1025708ebce4182975e522 100644 --- a/doc/paddle/api/paddle/io/load_program_state_cn.rst +++ b/doc/paddle/api/paddle/static/load_program_state_cn.rst @@ -22,8 +22,11 @@ load_program_state .. code-block:: python + import paddle import paddle.fluid as fluid + paddle.enable_static() + x = fluid.data( name="x", shape=[10, 10], dtype='float32') y = fluid.layers.fc( x, 10) z = fluid.layers.fc( y, 10) diff --git a/doc/paddle/api/paddle/io/save_inference_model_cn.rst b/doc/paddle/api/paddle/static/save_inference_model_cn.rst similarity index 98% rename from doc/paddle/api/paddle/io/save_inference_model_cn.rst rename to doc/paddle/api/paddle/static/save_inference_model_cn.rst index 9a4b7a3d2d1eeec3fd5d6464e69a9e54b5df22ad..1e24e52497950267757979a8845d3b8f68f1d19e 100644 --- a/doc/paddle/api/paddle/io/save_inference_model_cn.rst +++ b/doc/paddle/api/paddle/static/save_inference_model_cn.rst @@ -37,8 +37,11 @@ save_inference_model .. code-block:: python + import paddle import paddle.fluid as fluid + paddle.enable_static() + path = "./infer_model" # 用户定义网络,此处以softmax回归为例 diff --git a/doc/paddle/api/paddle/io/set_program_state_cn.rst b/doc/paddle/api/paddle/static/set_program_state_cn.rst similarity index 96% rename from doc/paddle/api/paddle/io/set_program_state_cn.rst rename to doc/paddle/api/paddle/static/set_program_state_cn.rst index a2510b9d8e8a778d1ba10f0e5aee8f9c233df9a5..5cd9f790128d427dbf67f41c520a3212fa32ae81 100644 --- a/doc/paddle/api/paddle/io/set_program_state_cn.rst +++ b/doc/paddle/api/paddle/static/set_program_state_cn.rst @@ -24,8 +24,11 @@ set_program_state .. code-block:: python + import paddle import paddle.fluid as fluid + paddle.enable_static() + x = fluid.data( name="x", shape=[10, 10], dtype='float32') y = fluid.layers.fc( x, 10) z = fluid.layers.fc( y, 10) diff --git a/doc/paddle/api/paddle/tensor/creation/empty_like_cn.rst b/doc/paddle/api/paddle/tensor/creation/empty_like_cn.rst new file mode 100644 index 0000000000000000000000000000000000000000..7d4eea89a454d285a6b28a1cee38f9cf49de0b46 --- /dev/null +++ b/doc/paddle/api/paddle/tensor/creation/empty_like_cn.rst @@ -0,0 +1,31 @@ +.. _cn_api_tensor_empty_like: + +empty_like +------------------------------- + +.. py:function:: paddle.empty_like(shape, dtype=None, name=None) + + +该OP根据 ``x`` 的shape和数据类型 ``dtype`` 创建未初始化的Tensor。如果 ``dtype`` 为None,则Tensor的数据类型与 ``x`` 相同。 + +参数: + - **x** (Tensor) – 输入Tensor, 输出Tensor和x具有相同的形状,x的数据类型可以是bool,float16,float32,float64,int32,int64。 + - **dtype** (np.dtype|str, 可选)- 输出变量的数据类型,可以是bool,float16,float32,float64,int32,int64。若参数为None,则输出变量的数据类型和输入变量相同,默认值为None。 + - **name** (str,可选)- 具体用法请参见 :ref:`api_guide_Name`,一般无需设置,默认值为None。 + +返回:返回一个根据 ``x`` 和 ``dtype`` 创建并且尚未初始化的Tensor。 + +**代码示例**: + +.. code-block:: python + + import paddle + import numpy as np + + paddle.disable_static() # Now we are in imperative mode + paddle.set_device("cpu") # and use cpu device + + x = paddle.randn([2, 3], 'float32') + output = paddle.empty_like(x) + #[[1.8491974e+20 1.8037303e+28 1.7443726e+28] # uninitialized + # [4.9640171e+28 3.0186127e+32 5.6715899e-11]] # uninitialized diff --git a/doc/paddle/api/paddle/tensor/linalg/mv_cn.rst b/doc/paddle/api/paddle/tensor/linalg/mv_cn.rst new file mode 100644 index 0000000000000000000000000000000000000000..abe92f64d0f98da3d3c1956ad489de284cc86c55 --- /dev/null +++ b/doc/paddle/api/paddle/tensor/linalg/mv_cn.rst @@ -0,0 +1,38 @@ +.. _cn_api_tensor_mv: + +mv +------------------------------- + +.. py:function:: paddle.mv(x, vec, name=None) + +该op计算矩阵 ``x`` 和向量 ``vec`` 的乘积。 + +参数 +::::::::: + - **x** (Tensor) : 输入变量,类型为 Tensor,形状为 :math:`[M, N]`,数据类型为float32, float64。 + - **vec** (Tensor) : 输入变量,类型为 Tensor,形状为 :math:`[N]`,数据类型为float32, float64。 + - **name** (str,可选)- 具体用法请参见 :ref:`api_guide_Name` ,一般无需设置,默认值为None。 + +返回 +::::::::: + + - Tensor,矩阵 ``x`` 和向量 ``vec`` 的乘积。 + +代码示例 +:::::::::: + +.. code-block:: python + + # x: [M, N], vec: [N] + # paddle.mv(x, vec) # out: [M] + + import numpy as np + import paddle + + paddle.disable_static() + x_data = np.array([[2, 1, 3], [3, 0, 1]]).astype("float64") + x = paddle.to_tensor(x_data) + vec_data = np.array([3, 5, 1]) + vec = paddle.to_tensor(vec_data).astype("float64") + out = paddle.mv(x, vec) + paddle.enable_static() diff --git a/doc/paddle/api/paddle/text/datasets/movie_reviews/MovieReviews_cn.rst b/doc/paddle/api/paddle/text/datasets/movie_reviews/MovieReviews_cn.rst deleted file mode 100644 index b4c99bccf3c72776f9f805445791918d08282eda..0000000000000000000000000000000000000000 --- a/doc/paddle/api/paddle/text/datasets/movie_reviews/MovieReviews_cn.rst +++ /dev/null @@ -1,49 +0,0 @@ -.. _cn_api_text_datasets_MovieReviews: - -MovieReviews -------------------------------- - -.. py:class:: paddle.text.datasets.MovieReviews() - - -该类是对`NLTK movie reviews `_ 测试数据集的实现。 - -参数 -::::::::: - - data_file(str)- 保存压缩数据的路径,如果参数:attr:`download`设置为True, - 可设置为None。默认为None。 - - mode(str)- 'train'或 'test' 模式。默认为'train'。 - - download(bool)- 如果:attr:`data_file`未设置,是否自动下载数据集。默认为True。 - -返回值 -::::::::: -``Dataset``,NLTK movie reviews数据集实例。 - -代码示例 -::::::::: - -.. code-block:: python - - import paddle - from paddle.text.datasets import MovieReviews - - class SimpleNet(paddle.nn.Layer): - def __init__(self): - super(SimpleNet, self).__init__() - - def forward(self, word, category): - return paddle.sum(word), category - - paddle.disable_static() - - movie_reviews = MovieReviews(mode='train') - - for i in range(10): - word_list, category = movie_reviews[i] - word_list = paddle.to_tensor(word_list) - category = paddle.to_tensor(category) - - model = SimpleNet() - word_list, category = model(word_list, category) - print(word_list.numpy().shape, category.numpy()) - diff --git a/doc/paddle/beginners_guide/dygraph/DyGraph.md b/doc/paddle/beginners_guide/dygraph/DyGraph.md index 2e0d095ade986147a6f10b8fbd0d0835a5a4c7e1..29dbb786d4bc670a2c0a7dc0c7b1a513a2778f15 100644 --- a/doc/paddle/beginners_guide/dygraph/DyGraph.md +++ b/doc/paddle/beginners_guide/dygraph/DyGraph.md @@ -552,7 +552,7 @@ static_layer.save_inference_model(save_dirname, feed=[0], fetch=[0]) # 声明式编程中需要使用执行器执行之前已经定义好的网络 place = paddle.CPUPlace() exe = paddle.Executor(place) -program, feed_vars, fetch_vars = paddle.io.load_inference_model(save_dirname, exe) +program, feed_vars, fetch_vars = paddle.static.load_inference_model(save_dirname, exe) # 声明式编程中需要调用执行器的run方法执行计算过程 fetch, = exe.run(program, feed={feed_vars[0]: in_np}, fetch_list=fetch_vars) ``` diff --git a/doc/paddle/faq/train_cn.md b/doc/paddle/faq/train_cn.md index 3c677ac0b6ab2b85527405988419ee72251811fc..00469bd69f5588239573a2a3043caca92a86d54a 100644 --- a/doc/paddle/faq/train_cn.md +++ b/doc/paddle/faq/train_cn.md @@ -96,23 +96,19 @@ with fluid.dygraph.guard(fluid.CPUPlace()): ## 模型训练&评估 -##### 问题:在CPU上进行模型训练,如何使用多线程? +##### 问题:使用CPU进行模型训练,如何利用多处理器进行加速? -+ 答复:可以参考使用[ParallelExecutor API](https://www.paddlepaddle.org.cn/documentation/docs/zh/1.3/api_cn/fluid_cn.html#parallelexecutor)。 ++ 答复:在1.8版本的动态图模式下,CPU训练加速可以从以下两点进行配置: ----------- - -##### 问题:如何提高单CPU多线程利用率? - -+ 答复:线程数是设备同时并行执行程序的个数,可以将线程数设置为“CPU的个数*CPU的核数”。可以通过 +1. 使用多进程DataLoader加速数据读取:训练数据较多时,数据处理往往会成为训练速度的瓶颈,paddle提供了异步数据读取接口DataLoader,可以使用多进程进行数据加载,充分利用多处理的优势,具体使用方法及示例请参考API文档:[fluid.io.DataLLoader](https://www.paddlepaddle.org.cn/documentation/docs/en/api/io/DataLoader.html#dataloader)。 -`os.getenv("CPU_NUM")`或者`os.environ['CPU_NUM'] = str(2)`获取相关参数值。 +2. 推荐使用支持MKL(英特尔数学核心函数库)的paddle安装包,MKL相比Openblas等通用计算库在计算速度上有显著的优势,能够提升您的训练效率。 ---------- -##### 问题:使用NVIDIA多卡运行Paddle时报错,`Error:NCCL ContextMap`或者`Error:hang住`(log日志打印突然卡住),如何解决? +##### 问题:使用NVIDIA多卡运行Paddle时报错 Nccl error,如何解决? -+ 答复:参考[NCCL Tests](https://github.com/NVIDIA/nccl-tests)检测您的环境。如果检测不通过,请登录[NCCL官网](https://developer.nvidia.com/zh-cn)下载NCCl,安装后重新检测。 ++ 答复:这个错误大概率是环境配置不正确导致的,建议您使用NVIDIA官方提供的方法参考检测自己的环境是否配置正确。具体地,可以使用[ NCCL Tests ](https://github.com/NVIDIA/nccl-tests) 检测您的环境;如果检测不通过,请登录[ NCCL官网 ](https://developer.nvidia.com/zh-cn)下载NCCl,安装后重新检测。 ---------- @@ -128,34 +124,26 @@ with fluid.dygraph.guard(fluid.CPUPlace()): ---------- -##### 问题:训练过程中提示显存不足,如何处理? - -+ 答复:这是一种常见情况,你可以尝试调整`batch_size`大小,也可以更改网络模型,或者参考官方文档[显存分配与优化](https://www.paddlepaddle.org.cn/documentation/docs/zh/1.5/advanced_usage/best_practice/memory_optimize.html) 。建议用户使用[AI Studio 学习与 实训社区训练](https://aistudio.baidu.com/aistudio/index),获取免费GPU算力,速度更快。 - ----------- - -##### 问题:GPU显存占用过高,如何解决? +##### 问题:训练时报错提示显存不足,如何解决? -+ 答复:建议调整 `FLAGS_fraction_of_gpu_memory_to_use` ,并检查`batch_size` 。通过设置较小的`batch_size`能降低显存消耗;`FLAGS_fraction_of_gpu_memory_to_use`默认值为 =0.92, 当申请不到需要的显存时会直接报内存不足。如遇到此情况,可以先检查一下GPU卡是否被占用,再设置较小的值,以启动程序。 ++ 答复:可以尝试按如下方法解决: ----------- +1. 检查是当前模型是否占用了过多显存,可尝试减小`batch_size` ; -##### 问题:GPU内存不足,报错 `Error:Out of memory error GPU`,如何处理? - -+ 问题描述: +2. 开启以下三个选项: -![图片](https://agroup-bos-bj.cdn.bcebos.com/bj-3cbc8370534cb998f321af9b32aa2859403d9c9d) +``` +#一旦不再使用即释放内存垃圾,=1.0 垃圾占用内存大小达到10G时,释放内存垃圾` +export FLAGS_eager_delete_tensor_gb=0.0` +#启用快速垃圾回收策略,不等待cuda kernel 结束,直接释放显存` +export FLAGS_fast_eager_deletion_mode=1` +#该环境变量设置只占用0%的显存` +export FLAGS_fraction_of_gpu_memory_to_use=0` +``` -+ 解决方案: +详细请参考官方文档[存储分配与优化](https://www.paddlepaddle.org.cn/documentation/docs/zh/advanced_guide/performance_improving/singlenode_training_improving/memory_optimize.html) 调整相关配置。 - 1. 检查是当前模型是否占用内存过高,可尝试减小`batch_size` ; - 2. 开启以下三个选项: - `#一旦不再使用即释放内存垃圾,=1.0 垃圾占用内存大小达到10G时,释放内存垃圾` - `export FLAGS_eager_delete_tensor_gb=0.0` - `#启用快速垃圾回收策略,不等待cuda kernel 结束,直接释放显存` - `export FLAGS_fast_eager_deletion_mode=1` - `#该环境变量设置只占用0%的显存` - `export FLAGS_fraction_of_gpu_memory_to_use=0` +此外,建议您使用[AI Studio 学习与 实训社区训练](https://aistudio.baidu.com/aistudio/index),获取免费GPU算力,提升您的训练效率。 ---------- @@ -163,20 +151,11 @@ with fluid.dygraph.guard(fluid.CPUPlace()): + 答复:有如下两点建议: - 1. 如果数据预处理耗时较长,可使用py_Reader 或 multiprocess_reader加速; - - 2. 如果提高GPU计算量,可以增加`batch_size`,但是注意调节其他超参数。 - - 以上两点均为比较通用的方案,其他的优化方案和模型相关,可参考相应models示例。 - ----------- - -##### 问题:使用CPU或GPU时,如何设置`num_threds`? + 1. 如果数据预处理耗时较长,可使用DataLoader加速数据读取过程,具体请参考API文档:[fluid.io.DataLLoader](https://www.paddlepaddle.org.cn/documentation/docs/en/api/io/DataLoader.html#dataloader)。 -+ 答复: + 2. 如果提高GPU计算量,可以增大`batch_size`,但是注意同时调节其他超参数以确保训练配置的正确性。 - 1. 如果是CPU,最大可以设置到当前CPU的内核数。 - 2. 如果是GPU,受显卡多处理器的寄存器数目限制,例如GeForce 8800GT的显卡,最多8192个寄存器。假设每个线程需要的寄存器等于16,则最多只有512个线程。再高的线程将会将数据切换的显卡显存,反而降低执行效率。 + 以上两点均为比较通用的方案,其他的优化方案和模型相关,可参考官方模型库 [models](https://github.com/PaddlePaddle/models) 中的具体示例。 ---------- @@ -184,44 +163,28 @@ with fluid.dygraph.guard(fluid.CPUPlace()): + 答复:请先参考[显存分配与优化文档](https://www.paddlepaddle.org.cn/documentation/docs/zh/1.5/advanced_usage/best_practice/memory_optimize.html) 开启存储优化开关,包括显存垃圾及时回收和Op内部的输出复用输入等。若存储空间仍然不够,建议: - 1. 降低`batch_size`; + 1. 降低 `batch_size` ; 2. 对index进行排序,减少padding的数量。 ---------- -##### 问题:Executor与ParallelExecutor有什么区别? - -+ 答复:如果没有指定Scope,所有的Executor都会共享一个Scope,即`global_scope`。 - -1. `fluid.Executor`执行对象是Program,可以认为是一个轻量级的执行器,目前主要用于参数初始化、参数加载、参数模型保存。 - -2. `fluid.ParallelExecutor`的执行对象是Graph,ParallelExecutor内部会将Program转为Graph,这样更便于对模型进行分析。 - ----------- - ##### 问题:训练过程中如果出现不收敛的情况,如何处理? + 答复:不收敛的原因有很多,可以参考如下方式排查: - 1. 检查数据集中训练数据的准确率,数据是否有很多错误,特征是否归一化; + 1. 检查数据集中训练数据的准确率,数据是否有错误,特征是否归一化; 2. 简化网络结构,先基于benchmark实验,确保在baseline网络结构和数据集上的收敛结果正确; 3. 对于复杂的网络,每次只增加一个改动,确保改动后的网络正确; 4. 检查网络在训练数据上的Loss是否下降; 5. 检查学习率、优化算法是否合适,学习率过大会导致不收敛; 6. 检查`batch_size`设置是否合适,`batch_size`过小会导致不收敛; - 7. 检查梯度计算是否正确,是否有梯度过大的情况,是否为NaN。 + 7. 检查梯度计算是否正确,是否有梯度过大的情况,是否为`NaN`。 ---------- ##### 问题:Loss为NaN,如何处理? -+ 答复:可能由于网络的设计问题,Loss过大(Loss为NaN)会导致梯度爆炸。如果没有改网络结构,但是出现了NaN,可能是数据读取导致,比如标签对应关系错误。 - ----------- - -##### 问题:在AI Studio上使用GPU训练时报错 `Attempt to use GPU for prediction, but environment variable CUDA_VISIBLE_DEVICES was not set correctly.`,如何处理? - -+ 答复:需要在Notebook环境中增加:`%set_env CUDA_VISIBLE_DEVICES=0`。 ++ 答复:可能是网络设计存在问题,Loss过大(Loss为NaN)会导致梯度爆炸。如果没有改网络结构,但是出现了NaN,可能是数据读取导致,比如标签对应关系错误。 ---------- @@ -238,7 +201,33 @@ with fluid.dygraph.guard(fluid.CPUPlace()): ##### 问题:增量训练中,如何保存模型和恢复训练? -+ 答复:在增量训练过程中,不仅需要保存模型的参数,也需要保存模型训练的状态(如learning_rate)。使用[save_persistables](https://www.paddlepaddle.org.cn/documentation/docs/zh/1.5/api_cn/dygraph_cn.html#save-persistables)保存模型训练的参数和状态;恢复训练时,使用[load_persistables](https://www.paddlepaddle.org.cn/documentation/docs/zh/1.5/api_cn/dygraph_cn.html#load-persistables)进行恢复训练。 ++ 答复:在增量训练过程中,不仅需要保存模型的参数,也需要保存优化器的参数。 + +具体地,在1.8版本中需要使用Layer和Optimizer的`state_dict`和`set_dict`方法配合`fluid.save_dygraph/load_dygraph`使用。简要示例如下: + +``` +import paddle.fluid as fluid + +with fluid.dygraph.guard(): + emb = fluid.dygraph.Embedding([10, 10]) + + state_dict = emb.state_dict() + fluid.save_dygraph(state_dict, "paddle_dy") + + adam = fluid.optimizer.Adam( learning_rate = fluid.layers.noam_decay( 100, 10000), + parameter_list = emb.parameters() ) + + state_dict = adam.state_dict() + fluid.save_dygraph(state_dict, "paddle_dy") + + para_state_dict, opti_state_dict = fluid.load_dygraph("paddle_dy") + emb.set_dict(para_state_dict) + adam.set_dict(opti_state_dict) +``` + +更多介绍请参考以下API文档: +- [save_dygraph](https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/dygraph_cn/save_dygraph_cn.html#save-dygraph) +- [load_dygraph](https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/dygraph_cn/load_dygraph_cn.html#load-dygraph) ---------- diff --git a/doc/paddle/guides/broadcasting_cn.rst b/doc/paddle/guides/broadcasting_cn.rst new file mode 100644 index 0000000000000000000000000000000000000000..4962ae919544da957bb9ae8282aed423a77fbbf0 --- /dev/null +++ b/doc/paddle/guides/broadcasting_cn.rst @@ -0,0 +1,99 @@ +.. _cn_user_guide_broadcasting: + +================== +广播 (broadcasting) +================== + +飞桨(PaddlePaddle,以下简称Paddle)和其他框架一样,提供的一些API支持广播(broadcasting)机制,允许在一些运算时使用不同形状的张量。 +通常来讲,如果有一个形状较小和一个形状较大的张量,我们希望多次使用较小的张量来对较大的张量执行一些操作,看起来像是较小形状的张量的形状首先被扩展到和较大形状的张量一致,然后做运算。 +值得注意的是,这期间并没有对较小形状张量的数据拷贝操作。 + +飞桨的广播机制主要遵循如下规则(参考 `Numpy 广播机制 `_ ): + +1. 每个张量至少为一维张量 +2. 从后往前比较张量的形状,当前维度的大小要么相等,要么其中一个等于一,要么其中一个不存在 + +例如: + +.. code-block:: python + + import paddle + import numpy as np + + paddle.disable_static() + + x = paddle.to_tensor(np.ones((2, 3, 4), np.float32)) + y = paddle.to_tensor(np.ones((2, 3, 4), np.float32)) + # 两个张量 形状一致,可以广播 + + x = paddle.to_tensor(np.ones((2, 3, 1, 5), np.float32)) + y = paddle.to_tensor(np.ones((3, 4, 1), np.float32)) + # 从后向前依次比较: + # 第一次:y的维度大小是1 + # 第二次:x的维度大小是1 + # 第三次:x和y的维度大小相等 + # 第四次:y的维度不存在 + # 所以 x和y是可以广播的 + + # 相反 + x = paddle.to_tensor(np.ones((2, 3, 4), np.float32)) + y = paddle.to_tensor(np.ones((2, 3, 6), np.float32)) + # 此时x和y是不可广播的,因为第一次比较 4不等于6 + +现在我们知道什么情况下两个张量是可以广播的,两个张量进行广播语义后的结果张量的形状计算规则如下: + +1. 如果两个张量的形状的长度不一致,那么需要在较小形状长度的矩阵像前添加1,只到两个张量的形状长度相等。 +2. 保证两个张量形状相等之后,每个维度上的结果维度就是当前维度上较大的那个。 + +例如: + +.. code-block:: python + + import paddle + import numpy as np + + paddle.disable_static() + + x = paddle.to_tensor(np.ones((2, 1, 4), np.float32)) + y = paddle.to_tensor(np.ones((3, 1), np.float32)) + z = x + y + print(z.shape) + # z的形状: [2,3,4] + + x = paddle.to_tensor(np.ones((2, 1, 4), np.float32)) + y = paddle.to_tensor(np.ones((3, 2), np.float32)) + z = x + y + print(z.shape) + # InvalidArgumentError: Broadcast dimension mismatch. + +除此之外,飞桨的elementwise系列API针对广播机制增加了axis参数,当使用较小形状的y来来匹配较大形状的x的时候,且满足y的形状的长度小于x的形状长度, +axis表示y在x上应用广播机制的时候的起始维度的位置,当设置了asis参数后,张量的维度比较顺序变成了从axis开始,从前向后比较。当axis=-1时,axis = rank(x) - rank(y), +同时y的大小为1的尾部维度将被忽略。 + +例如: + +.. code-block:: python + + import paddle + import numpy as np + + paddle.disable_static() + + x = paddle.to_tensor(np.ones((2, 1, 4), np.float32)) + y = paddle.to_tensor(np.ones((3, 1), np.float32)) + z = paddle.elementwise_add(x, y, axis=1) + # z的形状 [2, 3, 4] + + x = paddle.to_tensor(np.ones((2, 3, 4, 5), np.float32)) + y = paddle.to_tensor(np.ones((4, 5), np.float32)) + z = paddle.elementwise_add(x, y, axis=1) + print(z.shape) + # InvalidArgumentError: Broadcast dimension mismatch. + # 因为指定了axis之后,计算广播的维度从axis开始从前向后比较 + + x = paddle.to_tensor(np.ones((2, 3, 4, 5), np.float32)) + y = paddle.to_tensor(np.ones((3), np.float32)) + z = paddle.elementwise_add(x, y, axis=1) + print(z.shape) + # z的形状 [2, 3, 4, 5] + # 因为此时是从axis=1的维度开始,从前向后比较维度进行广播 diff --git a/doc/paddle/guides/broadcasting_en.rst b/doc/paddle/guides/broadcasting_en.rst new file mode 100644 index 0000000000000000000000000000000000000000..fcc8aff9d95c2cc217cf03d7f93233e65115098e --- /dev/null +++ b/doc/paddle/guides/broadcasting_en.rst @@ -0,0 +1,101 @@ +.. _user_guide_broadcasting: + +================== +Broadcasting +================== + +PaddlePaddle provides broadcasting semantics in some APIs like other deep learning frameworks, which allows using tensors with different shapes while operating. +In General, broadcast is the rule how the smaller tensor is “broadcast” across the larger tsnsor so that they have same shapes. +Note that no copies happened while broadcasting. + +In Paddlepaddle, tensors are broadcastable when following rulrs hold(ref: `Numpy Broadcasting `_ ): + +1. there should be at least one dimention in each tensor +2. when we compare their shapes element-wise from backward to forward, two dimensions are compatible when +they are equal, or one of them is 1, or one of them does not exist. + +For example: + +.. code-block:: python + + import paddle + import numpy as np + + paddle.disable_static() + + x = paddle.to_tensor(np.ones((2, 3, 4), np.float32)) + y = paddle.to_tensor(np.ones((2, 3, 4), np.float32)) + # Two tensor have some shpes are broadcastable + + x = paddle.to_tensor(np.ones((2, 3, 1, 5), np.float32)) + y = paddle.to_tensor(np.ones((3, 4, 1), np.float32)) + # compare from backward to forward: + # 1st step:y's dimention is 1 + # 2nd step:x's dimention is 1 + # 3rd step:two dimentions are the same + # 4st step:y's dimention does not exist + # So, x and y are broadcastable + + # In Compare + x = paddle.to_tensor(np.ones((2, 3, 4), np.float32)) + y = paddle.to_tensor(np.ones((2, 3, 6), np.float32)) + # x and y are not broadcastable because in first step form tail, x's dimention 4 is not equal to y's dimention 6 + +Now we know in what condition two tensors are broadcastable, how to calculate the resulting tensor's size follows the rules: + +1. If the number of dimensions of x and y are not equal, prepend 1 to the dimensions of the tensor with fewer dimensions to make them equal length. +2. Then, for each dimension size, the resulting dimension size is the max of the sizes of x and y along that dimension. + +For example: + +.. code-block:: python + + import paddle + import numpy as np + + paddle.disable_static() + + x = paddle.to_tensor(np.ones((2, 1, 4), np.float32)) + y = paddle.to_tensor(np.ones((3, 1), np.float32)) + z = x + y + print(z.shape) + # z'shape: [2,3,4] + + x = paddle.to_tensor(np.ones((2, 1, 4), np.float32)) + y = paddle.to_tensor(np.ones((3, 2), np.float32)) + z = x + y + print(z.shape) + # InvalidArgumentError: Broadcast dimension mismatch. + +In addition, axis is introduced to PaddlePaddle's broadcasting semantics. when using smaller shape tensor y to broadcast a larger tensor x, +and y's length of dimentions is smaller than x's, we can specify a aixs to indicate the starting dimention to do broadcasting. +In this case, the comparation on dimentions runs from forward to backward started at axis. when axis=-1, axis = rank(x) - rank(y). +when the last dimention of y is 1, it will be ignored. + +For example: + +.. code-block:: python + + import paddle + import numpy as np + + paddle.disable_static() + + x = paddle.to_tensor(np.ones((2, 1, 4), np.float32)) + y = paddle.to_tensor(np.ones((3, 1), np.float32)) + z = paddle.elementwise_add(x,y,axis=1) + # z'shape [2, 3, 4] + + x = paddle.to_tensor(np.ones((2, 3, 4, 5), np.float32)) + y = paddle.to_tensor(np.ones((4, 5), np.float32)) + z = paddle.elementwise_add(x, y, axis=1) + print(z.shape) + # InvalidArgumentError: Broadcast dimension mismatch. + # axis is indicated, comparation between dimentions starts at axis. + + x = paddle.to_tensor(np.ones((2, 3, 4, 5), np.float32)) + y = paddle.to_tensor(np.ones((3), np.float32)) + z = paddle.elementwise_add(x, y, axis=1) + print(z.shape) + # z'shape [2, 3, 4, 5] + # Start comparation at axis=1 from forward to backward. diff --git a/doc/paddle/guides/dygraph_to_static/basic_usage_cn.rst b/doc/paddle/guides/dygraph_to_static/basic_usage_cn.rst index 1a249870e65dd6e1f6471300f837ccf8f77c3d12..ac63908891fb79ac2f0d4026e9e0b99934f79624 100644 --- a/doc/paddle/guides/dygraph_to_static/basic_usage_cn.rst +++ b/doc/paddle/guides/dygraph_to_static/basic_usage_cn.rst @@ -111,7 +111,7 @@ trace是指在模型运行时记录下其运行过哪些算子。TracedLayer就 place = paddle.CPUPlace() exe = paddle.Executor(place) - program, feed_vars, fetch_vars = paddle.io.load_inference_model(save_dirname, exe) + program, feed_vars, fetch_vars = paddle.static.load_inference_model(save_dirname, exe) fetch, = exe.run(program, feed={feed_vars[0]: in_np}, fetch_list=fetch_vars) diff --git a/doc/paddle/guides/dygraph_to_static/basic_usage_en.rst b/doc/paddle/guides/dygraph_to_static/basic_usage_en.rst index f8b30dd74a3475371079d133dc879210466c8a68..ca3bf099fcb7aea07e04a9fa1b16b8ff5804340f 100644 --- a/doc/paddle/guides/dygraph_to_static/basic_usage_en.rst +++ b/doc/paddle/guides/dygraph_to_static/basic_usage_en.rst @@ -109,7 +109,7 @@ Load model and run it in static graph mode: place = paddle.CPUPlace() exe = paddle.Executor(place) - program, feed_vars, fetch_vars = paddle.io.load_inference_model(save_dirname, exe) + program, feed_vars, fetch_vars = paddle.static.load_inference_model(save_dirname, exe) fetch, = exe.run(program, feed={feed_vars[0]: in_np}, fetch_list=fetch_vars) However, as tracing only records operators once, if user's code contains Tensor-dependent (including Tensor value or Tensor shape) control flow, that is the Tensor can cause different operators being executed, then TracedLayer cannot handle this case. For instance: diff --git a/doc/paddle/guides/index_cn.rst b/doc/paddle/guides/index_cn.rst index 22c01a2181ef8af898663ddcf6af1708ee994c5b..73af7046db7075eed0ae77843e7e808f40e1969e 100644 --- a/doc/paddle/guides/index_cn.rst +++ b/doc/paddle/guides/index_cn.rst @@ -2,23 +2,26 @@ 使用教程 ######## -PaddlePaddle (PArallel Distributed Deep LEarning)是一个易用、高效、灵活、可扩展的深度学习框架。 +飞桨开源框架(PaddlePaddle)是一个易用、高效、灵活、可扩展的深度学习框架。 -您可参考PaddlePaddle的 `Github `_ 了解详情,也可阅读 `版本说明 <../release_note_cn.html>`_ 了解新版本的特性。 +您可参考飞桨框架的 `Github `_ 了解详情,也可阅读 `版本说明 <../release_note_cn.html>`_ 了解2.0beta版本的特性。 -让我们从学习PaddlePaddle基本概念这里开始: +让我们从学习飞桨的基本概念这里开始: - -- `Tensor概念介绍 `_ : 飞桨中数据的表示方式,Tensor概念介绍, -- `版本迁移 <./migration_cn.html>`_:介绍 Paddle 1 到Paddle 2的变化与Paddle1to2转换工具的使用。 -- `动态图转静态图 <./dygraph_to_static/index_cn.html>`_:介绍 Paddle 动态图转静态图的方法 -- `模型存储与载入 <./model_save_load_cn.html>`_:介绍 Paddle 模型与参数存储载入的方法 +- `Tensor概念介绍 <./tensor_introduction_cn.html>`_ : 飞桨中数据的表示方式,Tensor概念介绍。 +- `飞桨广播介绍 <./broadcasting_cn.html>`_ : 飞桨中广播概念的介绍。 +- `飞桨框架2.0beta升级指南 <./upgrade_guide_cn.html>`_: 介绍飞桨开源框架2.0beta的主要变化和如何升级。 +- `版本迁移工具 <./migration_cn.html>`_: 介绍paddle1to2转换工具的使用。 +- `动态图转静态图 <./dygraph_to_static/index_cn.html>`_: 介绍飞桨动态图转静态图的方法 +- `模型存储与载入 <./model_save_load_cn.html>`_: 介绍飞桨模型与参数存储载入的方法 .. toctree:: :hidden: - tensor_introduction.md + tensor_introduction_cn.md + broadcasting_cn.rst + upgrade_guide_cn.md migration_cn.rst dygraph_to_static/index_cn.rst model_save_load_cn.rst diff --git a/doc/paddle/guides/index_en.rst b/doc/paddle/guides/index_en.rst index 5a9837507b0bdd242c3f547ecaa31ce773c8fa72..a68f8847582c8a5394e796ba572ba212942f48d1 100644 --- a/doc/paddle/guides/index_en.rst +++ b/doc/paddle/guides/index_en.rst @@ -10,6 +10,7 @@ Please refer to `PaddlePaddle Github `_ Let's start with studying basic concept of PaddlePaddle: - `Introduction to Tensor `_ : Introduction of Tensor, which is the representation of data in Paddle. +- `broadcasting <./broadcasting_en.html>`_ : Introduction of broadcasting. - `migration tools <./migration_en.html>`_:how to use migration tools to upgrade your code. - `dynamic to static <./dygraph_to_static/index_en.html>`_:how to convert your model from dynamic graph to static graph. @@ -17,5 +18,6 @@ Let's start with studying basic concept of PaddlePaddle: :hidden: tensor_introduction_en.md + broadcasting_en.md migration_en.rst dygraph_to_static/index_en.rst diff --git a/doc/paddle/guides/migration_cn.rst b/doc/paddle/guides/migration_cn.rst index efd559c5fe334ba44fb8cdbee15e3f7dbd1ed7c3..9f378f00f0be96c5edfd48bb2735ada6b8b3e71a 100644 --- a/doc/paddle/guides/migration_cn.rst +++ b/doc/paddle/guides/migration_cn.rst @@ -1,47 +1,21 @@ -版本迁移 +版本迁移工具 ==================== -飞桨框架v2.0-beta,最重要的变化为API体系的全面升级以及动态图能力的全面完善。下文将简要介绍Paddle -2的变化。 +在飞桨框架2.0beta中,我们API的位置、命名、参数、行为,进行了系统性的调整和规范, 将API体系从1.X版本的 ``paddle.fluid.*`` 迁移到了 ``paddle.*`` 下。paddle.fluid目录下暂时保留了1.8版本API,主要是兼容性考虑,未来会被删除。 -主要变化 --------- - -在飞桨框架v2.0中,我们做了许多的升级。首先,全面完善了动态图模式,相较于静态图而言,动态图每次执行一个运算,可以立即得到结果,能够使算法的开发变得更加高效。此外,本版本对API目录,进行了较大的调整。将API体系从1.X版本的 -``paddle.fluid.*`` 迁移到了 ``paddle.*`` 下。原则上,Paddle -2仍支持Paddle 1下的所有语法。但是,我们会逐步废弃掉 ``paddle.fluid`` -下的API,强烈建议您将Paddle 1的代码迁移到Paddle -2下,以避免后续带来不必要的麻烦。下文将介绍手动与自动两种方式,来完成Paddle -1到Paddle 2的迁移。 - -手动将Paddle 1 的代码迁移到 Paddle 2 ------------------------------------- - -本节将介绍如何将您的代码手动的从Paddle 1迁移到Paddle 2。 - -1、API的变化 -~~~~~~~~~~~~ - -对于Paddle -1下的API,您可以通过我们提供的API升级表(TODO),查看每个API的升级关系,从而手动完成修改。 -### 2、句法的变化 在Paddle 1中,通过 ``with fluid.dygraph.guard():`` -开启动态图模式,在Paddle 2.0-beta中,可以直接通过 -``paddle.disable_static()``\ 开启动态图。 - -Paddle1to2 自动迁移您的代码到Paddle2 +使用版本迁移工具自动迁移您的paddle1.x的代码到Paddle2.0beta的代码 ------------------------------------ -Paddle 2 包含了许多API的变化,为了节约您将代码从Paddle 1迁移到Paddle -2的时间,我们提供了自动迁移工具–Paddle1to2,能够帮助您快速完成代码迁移。 +WARNING: 版本自动迁移工具并不能处理所有的情况,在使用本工具后,您仍然需要手工来进行检查并做相应的调整。 安装 ~~~~ -Paddle1to2可以通过pip的方式安装,方式如下: +paddle1to2工具可以通过pip的方式安装,方式如下: .. code:: ipython3 - ! pip install -U paddle1to2 + $ pip install -U paddle1to2 基本用法 ~~~~~~~~ @@ -50,14 +24,13 @@ Paddle1to2 可以使用下面的方式,快速使用: .. code:: ipython3 - ! paddle1to2 --inpath /path/to/model.py + $ paddle1to2 --inpath /path/to/model.py -这将在命令行中,以\ ``diff``\ 的形式,展示model.py从Paddle 1转换为Paddle -2的变化。如果您确认上述变化没有问题,只需要再执行: +这将在命令行中,以\ ``diff``\ 的形式,展示model.py从Paddle1.x转换为Paddle2.0beta的变化。如果您确认上述变化没有问题,只需要再执行: .. code:: ipython3 - ! paddle1to2 --inpath /path/to/model.py --write + $ paddle1to2 --inpath /path/to/model.py --write 就会原地改写model.py,将上述变化改写到您的源文件中。 注意:我们会默认备份源文件,到~/.paddle1to2/下。 @@ -86,26 +59,23 @@ Paddle1to2 可以使用下面的方式,快速使用: 开始 ^^^^ -在使用Paddle 1to2前,需要确保您已经安装了Paddle 2.0-beta版本。 +在使用paddle1to2前,需要确保您已经安装了Paddle2.0beta版本。 .. code:: ipython3 import paddle print (paddle.__version__) - # TODO change to paddle 2.0-beta - .. parsed-literal:: - 0.0.0 + 2.0.0-beta0 -克隆\ `PaddlePaddle/models `__\ 来作为工具的测试。 +克隆\ `paddlePaddle/models `__\ 来作为工具的测试。 .. code:: ipython3 - ! git clone https://github.com/PaddlePaddle/models - + $ git clone https://github.com/PaddlePaddle/models .. parsed-literal:: @@ -121,90 +91,89 @@ Paddle1to2 可以使用下面的方式,快速使用: 查看帮助文档 ^^^^^^^^^^^^ -paddle1to2 会随着 paddle -2.0-beta安装。所以您可以直接通过下面的方式,查看帮助文档。 +您可以直接通过下面的方式,查看帮助文档。 .. code:: ipython3 - ! paddle1to2 -h + $ paddle1to2 -h .. parsed-literal:: - usage: paddle1to2 [-h] [--log-level {DEBUG,INFO,WARNING,ERROR}] - [--no-log-file] [--log-filepath LOG_FILEPATH] --inpath - INPATH [--backup [BACKUP]] [--write] [--no-confirm] - [--refactor {refactor_import,norm_api_alias,args_to_kwargs,refactor_kwargs,api_rename,refactor_with,post_refactor}] - [--print-match] - - optional arguments: - -h, --help show this help message and exit - --log-level {DEBUG,INFO,WARNING,ERROR} - set log level, default is INFO - --no-log-file don't log to file - --log-filepath LOG_FILEPATH - set log file path, default is "report.log" - --inpath INPATH the file or directory path you want to upgrade. - --backup [BACKUP] backup directory, default is the "~/.paddle1to2/". - --write modify files in-place. - --no-confirm write files in-place without confirm, ignored without - --write. - --refactor {refactor_import,norm_api_alias,args_to_kwargs,refactor_kwargs,api_rename,refactor_with,post_refactor} - this is a debug option. Specify refactor you want to - run. If none, all refactors will be run. - --print-match this is a debug option. Print matched code and node - for each file. - - -Paddle 1的例子 + usage: paddle1to2 [-h] [--log-level {DEBUG,INFO,WARNING,ERROR}] + [--no-log-file] [--log-filepath LOG_FILEPATH] --inpath + INPATH [--backup [BACKUP]] [--write] [--no-confirm] + [--refactor {refactor_import,norm_api_alias,args_to_kwargs,refactor_kwargs,api_rename,refactor_with,post_refactor}] + [--print-match] + + optional arguments: + -h, --help show this help message and exit + --log-level {DEBUG,INFO,WARNING,ERROR} + set log level, default is INFO + --no-log-file don't log to file + --log-filepath LOG_FILEPATH + set log file path, default is "report.log" + --inpath INPATH the file or directory path you want to upgrade. + --backup [BACKUP] backup directory, default is the "~/.paddle1to2/". + --write modify files in-place. + --no-confirm write files in-place without confirm, ignored without + --write. + --refactor {refactor_import,norm_api_alias,args_to_kwargs,refactor_kwargs,api_rename,refactor_with,post_refactor} + this is a debug option. Specify refactor you want to + run. If none, all refactors will be run. + --print-match this is a debug option. Print matched code and node + for each file. + + +paddle1.x的例子 ^^^^^^^^^^^^^^ -这里是一个基于Paddle 1实现的一个mnist分类,部分内容如下: +这里是一个基于paddle1.x实现的一个mnist分类,部分内容如下: .. code:: ipython3 - ! head -n 198 models/dygraph/mnist/train.py | tail -n 20 + $ head -n 198 models/dygraph/mnist/train.py | tail -n 20 -.. parsed-literal:: +.. code:: ipython3 - with fluid.dygraph.guard(place): - if args.ce: - print("ce mode") - seed = 33 - np.random.seed(seed) - fluid.default_startup_program().random_seed = seed - fluid.default_main_program().random_seed = seed - - if args.use_data_parallel: - strategy = fluid.dygraph.parallel.prepare_context() - mnist = MNIST() - adam = AdamOptimizer(learning_rate=0.001, parameter_list=mnist.parameters()) - if args.use_data_parallel: - mnist = fluid.dygraph.parallel.DataParallel(mnist, strategy) - - train_reader = paddle.batch( - paddle.dataset.mnist.train(), batch_size=BATCH_SIZE, drop_last=True) - if args.use_data_parallel: - train_reader = fluid.contrib.reader.distributed_batch_reader( - train_reader) - - -使用Paddle1to2进行转化 + with fluid.dygraph.guard(place): + if args.ce: + print("ce mode") + seed = 33 + np.random.seed(seed) + fluid.default_startup_program().random_seed = seed + fluid.default_main_program().random_seed = seed + + if args.use_data_parallel: + strategy = fluid.dygraph.parallel.prepare_context() + mnist = MNIST() + adam = AdamOptimizer(learning_rate=0.001, parameter_list=mnist.parameters()) + if args.use_data_parallel: + mnist = fluid.dygraph.parallel.DataParallel(mnist, strategy) + + train_reader = paddle.batch( + paddle.dataset.mnist.train(), batch_size=BATCH_SIZE, drop_last=True) + if args.use_data_parallel: + train_reader = fluid.contrib.reader.distributed_batch_reader( + train_reader) + + +使用paddle1to2进行转化 ^^^^^^^^^^^^^^^^^^^^^^ paddle1to2支持单文件的转化,您可以通过下方的命令直接转化单独的文件。 .. code:: ipython3 - !paddle1to2 --inpath models/dygraph/mnist/train.py + $ paddle1to2 --inpath models/dygraph/mnist/train.py 注意,对于参数的删除及一些特殊情况,我们都会打印WARNING信息,需要您仔细核对相关内容。 如果您觉得上述信息没有问题,可以直接对文件进行原地修改,方式如下: .. code:: ipython3 - !paddle1to2 --inpath models/dygraph/mnist/train.py --write + $ paddle1to2 --inpath models/dygraph/mnist/train.py --write 此时,命令行会弹出下方的提示: @@ -220,15 +189,14 @@ paddle1to2支持单文件的转化,您可以通过下方的命令直接转化 .. code:: ipython3 - ! cat report.log + $ cat report.log 注意事项 ~~~~~~~~ - 本迁移工具不能完成所有API的迁移,有少量的API需要您手动完成迁移,具体信息可见WARNING。 -使用Paddle 2 +使用paddle 2 ~~~~~~~~~~~~ -完成迁移后,代码就从Paddle 1迁移到了Paddle 2,您就可以在Paddle -2下进行相关的开发。 +完成迁移后,代码就从paddle1.x迁移到了paddle2.0beta,您就可以在paddle2.0beta下进行相关的开发。 diff --git a/doc/paddle/guides/model_save_load_cn.rst b/doc/paddle/guides/model_save_load_cn.rst index 73d0f00724ab993974dfeed74ef350bf1bf27214..8f6273d36bad1d204052e28339f8bf76fcf34d02 100644 --- a/doc/paddle/guides/model_save_load_cn.rst +++ b/doc/paddle/guides/model_save_load_cn.rst @@ -25,16 +25,16 @@ .. image:: https://github.com/PaddlePaddle/FluidDoc/blob/develop/doc/paddle/guides/images/load_2.0.png?raw=true 1.2 静态图存储载入体系(飞桨框架1.x) ----------------------------- +-------------------------------- 静态图存储载入相关接口为飞桨框架1.x版本的主要使用接口,出于兼容性的目的,这些接口仍然可以在飞桨框架2.x使用,但不再推荐。相关接口包括: -- paddle.io.save -- paddle.io.load -- paddle.io.save_inference_model -- paddle.io.load_inference_model -- paddle.io.load_program_state -- paddle.io.set_program_state +- paddle.static.save +- paddle.static.load +- paddle.static.save_inference_model +- paddle.static.load_inference_model +- paddle.static.load_program_state +- paddle.static.set_program_state 由于飞桨框架2.0不再主推静态图模式,故本文不对以上主要用于飞桨框架1.x的相关接口展开介绍,如有需要,可以阅读对应API文档。 @@ -45,7 +45,7 @@ - paddle.Model.save - paddle.Model.load -飞桨框架2.0高阶API存储载入接口体系清晰,表意直观,若有需要,建议直接阅读相关API文档,此处不再赘述。 +飞桨框架2.0高阶API仅有一套Save/Load接口,表意直观,体系清晰,若有需要,建议直接阅读相关API文档,此处不再赘述。 .. note:: 本教程着重介绍飞桨框架2.x的各个存储载入接口的关系及各种使用场景,不对接口参数进行详细介绍,如果需要了解具体接口参数的含义,请直接阅读对应API文档。 @@ -56,10 +56,7 @@ 若仅需要存储/载入模型的参数,可以使用 ``paddle.save/load`` 结合Layer和Optimizer的state_dict达成目的,此处state_dict是对象的持久参数的载体,dict的key为参数名,value为参数真实的numpy array值。 -2.1 参数存储 ------------- - -参数存储时,先获取目标对象(Layer或者Optimzier)的state_dict,然后将state_dict存储至磁盘,示例如下: +结合以下简单示例,介绍参数存储和载入的方法,以下示例完成了一个简单网络的训练过程: .. code-block:: python @@ -128,20 +125,53 @@ # train train(layer, loader, loss_fn, adam) - # save - model_path = "linear_net" - param_state_dict = layer.state_dict() - paddle.save(param_state_dict, model_path) +2.1 参数存储 +------------ + +参数存储时,先获取目标对象(Layer或者Optimzier)的state_dict,然后将state_dict存储至磁盘,示例如下(接前述示例): - opt_state_dict = adam.state_dict() - paddle.save(opt_state_dict, model_path) +.. code-block:: python + + # save + paddle.save(layer.state_dict(), "linear_net.pdparams") + paddle.save(adam.state_dict(), "adam.pdopt") 2.2 参数载入 ------------ -参数载入时,先从磁盘载入保存的state_dict,然后通过set_state_dict方法配置到目标对象中,示例如下: +参数载入时,先从磁盘载入保存的state_dict,然后通过set_state_dict方法配置到目标对象中,示例如下(接前述示例): + +.. code-block:: python + + # load + layer_state_dict = paddle.load("linear_net.pdparams") + opt_state_dict = paddle.load("adam.pdopt") + + layer.set_state_dict(layer_state_dict) + adam.set_state_dict(opt_state_dict) + + +三、模型&参数存储载入(训练部署) +############################ + +若要同时存储/载入模型结构和参数,可以使用 ``paddle.jit.save/load`` 实现。 + +3.1 模型&参数存储 +---------------- + +模型&参数存储根据训练模式不同,有两种使用情况: + +(1) 动转静训练 + 模型&参数存储 +(2) 动态图训练 + 模型&参数存储 + +3.1.1 动转静训练 + 模型&参数存储 +`````````````````````````````` + +动转静训练相比直接使用动态图训练具有更好的执行性能,训练完成后,直接将目标Layer传入 ``paddle.jit.save`` 存储即可。: + +一个简单的网络训练示例如下: .. code-block:: python @@ -175,6 +205,7 @@ super(LinearNet, self).__init__() self._linear = nn.Linear(IMAGE_SIZE, CLASS_NUM) + @paddle.jit.to_static def forward(self, x): return self._linear(x) @@ -207,28 +238,20 @@ drop_last=True, num_workers=2) - # load - model_path = "linear_net" - param_state_dict, opt_state_dict = paddle.load(model_path) - - layer.set_state_dict(param_state_dict) - adam.set_state_dict(opt_state_dict) - # train train(layer, loader, loss_fn, adam) -.. note:: - ``paddle.load`` 接口可能仍会改动,后续可能改为仅返回一个单独的dict。 -三、模型&参数存储载入(训练部署) -############################ +随后使用 ``paddle.jit.save`` 对模型和参数进行存储(接前述示例): -若要同时存储/载入模型结构和参数,可以使用 ``paddle.jit.save/load`` 实现。 +.. code-block:: python -3.1 模型&参数存储 ----------------- + # save + model_path = "linear.example.model" + paddle.jit.save(layer, model_path) -同时存储模型和参数,需要结合动静转换功能使用。有以下三项注意点: + +通过动转静训练后保存模型&参数,有以下两项注意点: (1) Layer对象的forward方法需要经由 ``paddle.jit.to_static`` 装饰 @@ -322,9 +345,12 @@ Layer更准确的语义是描述一个具有预测功能的模型对象,接收 return self._linear(x) -(3) 使用 ``paddle.jit.save`` 存储模型和参数 +3.1.2 动态图训练 + 模型&参数存储 +`````````````````````````````` + +动态图模式相比动转静模式更加便于调试,如果您仍需要使用动态图直接训练,也可以在动态图训练完成后调用 ``paddle.jit.save`` 直接存储模型和参数。 -直接将目标Layer传入 ``paddle.jit.save`` 存储即可,完整示例如下: +同样是一个简单的网络训练示例: .. code-block:: python @@ -332,6 +358,7 @@ Layer更准确的语义是描述一个具有预测功能的模型对象,接收 import paddle import paddle.nn as nn import paddle.optimizer as opt + from paddle.static import InputSpec BATCH_SIZE = 16 BATCH_NUM = 4 @@ -358,7 +385,6 @@ Layer更准确的语义是描述一个具有预测功能的模型对象,接收 super(LinearNet, self).__init__() self._linear = nn.Linear(IMAGE_SIZE, CLASS_NUM) - @paddle.jit.to_static def forward(self, x): return self._linear(x) @@ -377,8 +403,6 @@ Layer更准确的语义是描述一个具有预测功能的模型对象,接收 place = paddle.CPUPlace() paddle.disable_static(place) - # 1. train & save model. - # create network layer = LinearNet() loss_fn = nn.CrossEntropyLoss() @@ -396,14 +420,47 @@ Layer更准确的语义是描述一个具有预测功能的模型对象,接收 # train train(layer, loader, loss_fn, adam) + +训练完成后使用 ``paddle.jit.save`` 对模型和参数进行存储: + +.. code-block:: python + # save - model_path = "linear.example.model" - paddle.jit.save(layer, model_path) + model_path = "linear.example.dy_model" + paddle.jit.save( + layer=layer, + model_path=model_path, + input_spec=[InputSpec(shape=[None, 784], dtype='float32')]) +动态图训练后使用 ``paddle.jit.save`` 存储模型和参数注意点如下: -.. note:: - 后续仍会优化此处的使用方式,支持不装饰 ``to_static`` 也能够通过 ``paddle.jit.save`` 直接存储模型和参数。 +(1) 相比动转静训练,Layer对象的forward方法不需要额外装饰,保持原实现即可 + +(2) 与动转静训练相同,请确保Layer.forward方法中仅实现预测功能,避免将训练所需的loss计算逻辑写入forward方法 + +(3) 在最后使用 ``paddle.jit.save`` 时,需要指定Layer的 ``InputSpec`` ,Layer对象forward方法的每一个参数均需要对应的 ``InputSpec`` 进行描述,不能省略。这里的 ``input_spec`` 参数支持两种类型的输入: + +- ``InputSpec`` 列表 +使用InputSpec描述forward输入参数的shape,dtype和name,如前述示例(此处示例中name省略,name省略的情况下会使用forward的对应参数名作为name,所以这里的name为 ``x`` ): + +.. code-block:: python + + paddle.jit.save( + layer=layer, + model_path=model_path, + input_spec=[InputSpec(shape=[None, 784], dtype='float32')]) + +- Example Tensor 列表 + +除使用InputSpec之外,也可以直接使用forward训练时的示例输入,此处可以使用前述示例中迭代DataLoader得到的 ``image`` ,示例如下: + +.. code-block:: python + + paddle.jit.save( + layer=layer, + model_path=model_path, + input_spec=[image]) 3.2 模型&参数载入 ---------------- @@ -512,7 +569,7 @@ Layer更准确的语义是描述一个具有预测功能的模型对象,接收 # load model_path = "linear.example.model" - state_dict, _ = paddle.load(model_path) + state_dict = paddle.load(model_path) # inference layer.set_state_dict(state_dict, use_structured_name=False) @@ -526,7 +583,7 @@ Layer更准确的语义是描述一个具有预测功能的模型对象,接收 如果您是从飞桨框架1.x切换到2.x,曾经使用飞桨框架1.x的接口存储模型或者参数,飞桨框架2.x也对这种情况进行了兼容性支持,包括以下几种情况。 -4.1 从 ``paddle.io.save_inference_model`` 存储结果中载入模型&参数 +4.1 从 ``paddle.static.save_inference_model`` 存储结果中载入模型&参数 ------------------------------------------------------------------ 曾用接口名为 ``paddle.fluid.io.save_inference_model`` 。 @@ -535,7 +592,7 @@ Layer更准确的语义是描述一个具有预测功能的模型对象,接收 使用 ``paddle.jit.load`` 配合 ``paddle.SaveLoadConfig`` 载入模型和参数。 -模型准备及训练示例,该示例为后续所有示例的前序逻辑: +飞桨1.x模型准备及训练示例,该示例为后续所有示例的前序逻辑: .. code-block:: python @@ -670,7 +727,7 @@ Layer更准确的语义是描述一个具有预测功能的模型对象,接收 model_path = "fc.example.model" - load_param_dict, _ = paddle.load(model_path) + load_param_dict = paddle.load(model_path) 如果您指定了存储的模型文件名,可以按照以下方式载入(接前述示例): @@ -680,7 +737,7 @@ Layer更准确的语义是描述一个具有预测功能的模型对象,接收 config = paddle.SaveLoadConfig() config.model_filename = "__simplenet__" - load_param_dict, _ = paddle.load(model_path, config) + load_param_dict = paddle.load(model_path, config) 如果您指定了存储的参数文件名,可以按照以下方式载入(接前述示例): @@ -690,7 +747,7 @@ Layer更准确的语义是描述一个具有预测功能的模型对象,接收 config = paddle.SaveLoadConfig() config.params_filename = "__params__" - load_param_dict, _ = paddle.load(model_path, config) + load_param_dict = paddle.load(model_path, config) .. note:: 一般预测模型不会存储优化器Optimizer的参数,因此此处载入的仅包括模型本身的参数。 @@ -698,12 +755,12 @@ Layer更准确的语义是描述一个具有预测功能的模型对象,接收 .. note:: 由于 ``structured_name`` 是动态图下独有的变量命名方式,因此从静态图存储结果载入的state_dict在配置到动态图的Layer中时,需要配置 ``Layer.set_state_dict(use_structured_name=False)`` 。 -4.2 从 ``paddle.io.save`` 存储结果中载入参数 +4.2 从 ``paddle.static.save`` 存储结果中载入参数 ---------------------------------------------- 曾用接口名为 ``paddle.fluid.save`` 。 - ``paddle.fluid.save`` 的存储格式与2.x动态图接口 ``paddle.save`` 存储格式是类似的,同样存储了dict格式的参数,因此可以直接使用 ``paddle.load`` 载入state_dict,示例如下(接前述示例): + ``paddle.fluid.save`` 的存储格式与2.x动态图接口 ``paddle.save`` 存储格式是类似的,同样存储了dict格式的参数,因此可以直接使用 ``paddle.load`` 载入state_dict,但需要注意不能仅传入保存的路径,而要传入保存参数的文件名,示例如下(接前述示例): .. code-block:: python @@ -715,22 +772,23 @@ Layer更准确的语义是描述一个具有预测功能的模型对象,接收 # enable dygraph mode paddle.disable_static(place) - load_param_dict, _ = paddle.load(model_path) + load_param_dict = paddle.load("fc.example.model.save.pdparams") .. note:: 由于 ``paddle.fluid.save`` 接口原先在静态图模式下的定位是存储训练时参数,或者说存储Checkpoint,故尽管其同时存储了模型结构,目前也暂不支持从 ``paddle.fluid.save`` 的存储结果中同时载入模型和参数,后续如有需求再考虑支持。 -4.3 从 ``paddle.io.save_params/save_persistables`` 存储结果中载入参数 ------------------------------------------------------------------------ +4.3 从 ``paddle.fluid.io.save_params/save_persistables`` 存储结果中载入参数 +------------------------------------------------------------------------- -.. note:: - 以下方式仅为暂时解决方案,后续计划会在 ``paddle.load`` 接口支持此功能。 +这两个接口在飞桨1.x版本时,已经不再推荐作为存储模型参数的接口使用,故并未继承至飞桨2.x,之后也不会再推荐使用这两个接口存储参数。 + +对于使用这两个接口存储参数兼容载入的支持,分为两种情况,下面以 ``paddle.fluid.io.save_params`` 接口为例介绍相关使用方法: -曾用接口名为 ``paddle.fluid.io.save_params/save_persistables`` 。 +(1) 使用默认方式存储,各参数分散存储为单独的文件,文件名为参数名 -此处可以使用 ``paddle.io.load_program_state`` 接口从以上两个接口的存储结果中载入state_dict,并用于动态图Layer的配置,示例如下(接前述示例): +这种存储方式仍然可以使用 ``paddle.load`` 接口兼容载入,使用示例如下(接前述示例): .. code-block:: python @@ -739,4 +797,23 @@ Layer更准确的语义是描述一个具有预测功能的模型对象,接收 fluid.io.save_params(exe, model_path) # load - state_dict = paddle.io.load_program_state(model_path) + state_dict = paddle.load(model_path) + print(state_dict) + +(2) 指定了参数存储的文件,将所有参数存储至单个文件中 + +将所有参数存储至单个文件中会导致存储结果中丢失Tensor名和Tensor数据之间的映射关系,因此这部分丢失的信息需要用户传入进行补足。为了确保正确性,这里不仅要传入Tensor的name列表,同时要传入Tensor的shape和dtype等描述信息,通过检查和存储数据的匹配性确保严格的正确性,这导致载入数据的恢复过程变得比较复杂,仍然需要一些飞桨1.x的概念支持。后续如果此项需求较为普遍,我们将会考虑将该项功能兼容支持到 ``paddle.load`` 中,但由于信息丢失而导致的使用复杂性仍然是存在的,因此建议您避免仅使用这两个接口存储参数。 + +目前暂时推荐您使用 ``paddle.static.load_program_state`` 接口解决此处的载入问题,需要获取原Program中的参数列表传入该方法,使用示例如下(接前述示例): + +.. code-block:: python + + # save by fluid.io.save_params + model_path = "fc.example.model.save_params_with_filename" + fluid.io.save_params(exe, model_path, filename="__params__") + + # load + import os + params_file_path = os.path.join(model_path, "__params__") + var_list = fluid.default_main_program().all_parameters() + state_dict = paddle.io.load_program_state(params_file_path, var_list) diff --git a/doc/paddle/guides/tensor_introduction.md b/doc/paddle/guides/tensor_introduction_cn.md similarity index 100% rename from doc/paddle/guides/tensor_introduction.md rename to doc/paddle/guides/tensor_introduction_cn.md diff --git a/doc/paddle/guides/upgrade_guide_cn.md b/doc/paddle/guides/upgrade_guide_cn.md new file mode 100644 index 0000000000000000000000000000000000000000..68179704157f5544e2249f3396106d343684faa6 --- /dev/null +++ b/doc/paddle/guides/upgrade_guide_cn.md @@ -0,0 +1,511 @@ +# 飞桨框架2.0beta升级指南 + +## 升级概要 +本版本是2.0版的公测版,相对1.8版本有重大升级,涉及开发方面的重要变化如下: + + - 动态图功能完善,动态图模下数据表示概念为Tensor,推荐使用动态图模式; + - API目录体系调整,API的命名和别名进行了统一规范化,虽然兼容老版API,但请使用新API体系开发; + - 数据处理、组网方式、模型训练、多卡启动、模型保存和推理等开发流程都有了对应优化,请对应查看说明; + +以上变化请仔细阅读本指南。对于已有模型的升级,我们还提供了2.0转换工具(见附录)提供更自动化的辅助。 +其他一些功能增加方面诸如动态图对量化训练、混合精度的支持、动静转换等方面不在本指南列出,具体可查看[Release Note](https://github.com/PaddlePaddle/Paddle/releases/tag/v2.0.0-beta0#)或对应文档。 + +## 一、动态图 + +### 推荐优先使用动态图模式 +飞桨2.0版本将会把动态图作为默认模式。2.0-beta版本虽然还未做默认切换,但推荐大家优先使用动态图模式,需要在程序开始时调用`paddle.disable_static`切换到动态图。2.0-rc版本后默认模式将切换为动态图,此行代码可删除。(2.0-rc版本后如果还想使用静态图,可通过调用`paddle.enable_static`切换)。 + +```python +import paddle + +# 2.0-beta版本需要调用下面代码,切换到动态图模式 +# 2.0-rc版本可以删除这一行 +paddle.disable_static() +``` + +### 使用Tensor概念表示数据 +静态图模式下,由于组网时使用的数据不能实时访问,Paddle用Variable来表示数据。 +动态图下,从直观性等角度考虑,将数据表示概念统一为Tensor。动态图下Tensor的创建主要有两种方法: + +1. 通过调用paddle.to_tensor函数,将python scalar/list,或者numpy.ndarray数据转换为Paddle的Tensor。具体使用方法,请查看官网的API文档。 + +```python +import paddle + +paddle.disable_static() +paddle.to_tensor(1) +paddle.to_tensor((1.1, 2.2)) +paddle.to_tensor(np.random.randn(3, 4)) +``` + +2. 通过调用 `paddle.zeros, paddle.ones, paddle.full, paddle.arange, paddle.rand, paddle.randn, paddle.randint, paddle.normal, paddle.uniform` 等函数,创建并返回Tensor。 + +## 二、API +### API目录结构 + +为了API组织更加简洁和清晰,将原来padddle.fluid.xxx的目录体系全新升级为paddle.xxx,并对子目录的组织进行了系统的条理化优化。同时还增加了高层API,可以高低搭配使用。paddle.fluid目录下暂时保留了1.8版本API,主要是兼容性考虑,未来会被删除。 +**基于2.0的开发任务,请使用paddle目录下的API,不要再使用paddle.fluid目录下的API。** 如果发现Paddle目录下有API缺失的情况,推荐使用基础API进行组合实现;您也可以通过在 [github](https://github.com/paddlepaddle/paddle) 上提issue的方式向我们反馈。 + +**2.0-beta版本的API 整体目录结构如下**: + +| 目录 | 功能和包含的API | +| :--- | --------------- | +| paddle.* | paddle根目录下保留了常用API的别名,当前包括:paddle.tensor和paddle.framework目录下的所有API | +| paddle.tensor | 跟tensor操作相关的API,比如:创建zeros, 矩阵运算matmul, 变换concat, 计算add, 查找argmax等 | +| paddle.nn | 跟组网相关的API,比如:Linear,卷积,LSTM,损失函数,激活函数等 | +| paddle.static.nn | 静态图下组网专用API,比如:输入占位符data, 全连接层fc, 控制流while_loop/cond | +| paddle.static | 静态图下基础框架相关API,比如:Variable, Program, Executor等 | +| paddle.framework | 框架通用API和动态图模式的API,比如:to_tensor, no_grad等 | +| paddle.optimizer | 优化算法相关API,比如:SGD,Adagrad, Adam等 | +| paddle.optimizer.lr_scheduler | 学习率衰减相关API | +| paddle.metric | 评估指标计算相关的API,比如:accuracy, auc等 | +| paddle.io | 数据输入输出相关API,比如:Dataset, DataLoader等 | +| paddle.device | 设备管理相关API,比如:CPUPlace, CUDAPlace等 | +| paddle.distributed | 分布式相关基础API | +| paddle.distributed.fleet | 分布式相关高层API | +| paddle.vision | 视觉领域API,比如,数据集,数据处理,常用基础网络结构,比如resnet | +| paddle.text | NLP领域API, 比如,数据集,数据处理,常用网络结构,比如Transformer | + +### API别名规则 + +- 为了方便用户使用,API会在不同的路径下建立别名: + - 所有framework, tensor目录下的API,均在paddle根目录建立别名;除少数特殊API外,其他API在paddle根目录下均没有别名。 + - paddle.nn目录下除functional目录以外的所有API,在paddle.nn目录下均有别名;functional目录中的API,在paddle.nn目录下均没有别名。 +- **推荐用户优先使用较短的路径的别名**,比如`paddle.add -> paddle.tensor.add`,推荐优先使用`paddle.add` +- 以下为一些特殊的别名关系,推荐使用左边的API名称: + - paddle.sigmoid -> paddle.tensor.sigmoid -> paddle.nn.functional.sigmoid + - paddle.tanh -> paddle.tensor.tanh -> paddle.nn.functional.tanh + - paddle.remainder -> paddle.mod -> paddle.floor_mod + - paddle.divide -> paddle.true_divide + - paddle.rand -> paddle.uniform + - paddle.randn -> paddle.standard_normal + - Optimizer.clear_grad -> Optimizer.clear_gradients + - Optimizer.set_state_dict -> Optimizer.set_dict + - Optimizer.get_lr -> Optimizer.current_step_lr + - Layer.clear_grad -> Layer.clear_gradients + - Layer.set_state_dict -> Layer.set_dict + +### 常用API名称变化 + +- 加、减、乘、除使用全称,不使用简称 +- 对于当前逐元素操作,不加elementwise前缀 +- 对于按照某一轴操作,不加reduce前缀 +- Conv, Pool, Dropout, BatchNorm, Pad组网类API根据输入数据类型增加1d, 2d, 3d后缀 + + | Paddle 1.8 API名称 | Paddle 2.0-beta 对应的名称| + | --------------- | ------------------------ | + | paddle.fluid.layers.elementwise_add | paddle.add | + | paddle.fluid.layers.elementwise_sub | paddle.subtract | + | paddle.fluid.layers.elementwise_mul | paddle.multiply | + | paddle.fluid.layers.elementwise_div | paddle.divide | + | paddle.fluid.layers.elementwise_max | paddle.maximum | + | paddle.fluid.layers.elementwise_min | paddle.minimum | + | paddle.fluid.layers.reduce_sum | paddle.sum | + | paddle.fluid.layers.reduce_prod | paddle.prod | + | paddle.fluid.layers.reduce_max | paddle.max | + | paddle.fluid.layers.reduce_min | paddle.min | + | paddle.fluid.layers.reduce_all | paddle.all | + | paddle.fluid.layers.reduce_any | paddle.any | + | paddle.fluid.dygraph.Conv2D | paddle.nn.Conv2d | + | paddle.fluid.dygraph.Conv2DTranspose | paddle.nn.ConvTranspose2d | + | paddle.fluid.dygraph.Pool2D | paddle.nn.MaxPool2d, paddle.nn.AvgPool2d | + +## 三、开发流程 +### 数据处理 +数据处理推荐使用**paddle.io目录下的Dataset,Sampler, BatchSampler, DataLoader接口**,不推荐reader类接口。一些常用的数据集已经在paddle.vision.datasets和paddle.text.datasets目录实现,具体参考API文档。 + +```python +from paddle.io import Dataset + +class MyDataset(Dataset): + """ + 步骤一:继承paddle.io.Dataset类 + """ + def __init__(self, mode='train'): + """ + 步骤二:实现构造函数,定义数据读取方式,划分训练和测试数据集 + """ + super(MyDataset, self).__init__() + + if mode == 'train': + self.data = [ + ['traindata1', 'label1'], + ['traindata2', 'label2'], + ['traindata3', 'label3'], + ['traindata4', 'label4'], + ] + else: + self.data = [ + ['testdata1', 'label1'], + ['testdata2', 'label2'], + ['testdata3', 'label3'], + ['testdata4', 'label4'], + ] + + def __getitem__(self, index): + """ + 步骤三:实现__getitem__方法,定义指定index时如何获取数据,并返回单条数据(训练数据,对应的标签) + """ + data = self.data[index][0] + label = self.data[index][1] + + return data, label + + def __len__(self): + """ + 步骤四:实现__len__方法,返回数据集总数目 + """ + return len(self.data) + +# 测试定义的数据集 +train_dataset = MyDataset(mode='train') +val_dataset = MyDataset(mode='test') + +print('=============train dataset=============') +for data, label in train_dataset: + print(data, label) + +print('=============evaluation dataset=============') +for data, label in val_dataset: + print(data, label) +``` + +### 组网方式 +#### Sequential 组网 + +针对顺序的线性网络结构我们可以直接使用Sequential来快速完成组网,可以减少类的定义等代码编写。 + +```python +import paddle +paddle.disable_static() + +# Sequential形式组网 +mnist = paddle.nn.Sequential( + paddle.nn.Flatten(), + paddle.nn.Linear(784, 512), + paddle.nn.ReLU(), + paddle.nn.Dropout(0.2), + paddle.nn.Linear(512, 10) +) +``` + +#### SubClass组网 + + 针对一些比较复杂的网络结构,就可以使用Layer子类定义的方式来进行模型代码编写,在`__init__`构造函数中进行组网Layer的声明,在`forward`中使用声明的Layer变量进行前向计算。子类组网方式也可以实现sublayer的复用,针对相同的layer可以在构造函数中一次性定义,在forward中多次调用。 + +```python +import paddle +paddle.disable_static() + +# Layer类继承方式组网 +class Mnist(paddle.nn.Layer): + def __init__(self): + super(Mnist, self).__init__() + + self.flatten = paddle.nn.Flatten() + self.linear_1 = paddle.nn.Linear(784, 512) + self.linear_2 = paddle.nn.Linear(512, 10) + self.relu = paddle.nn.ReLU() + self.dropout = paddle.nn.Dropout(0.2) + + def forward(self, inputs): + y = self.flatten(inputs) + y = self.linear_1(y) + y = self.relu(y) + y = self.dropout(y) + y = self.linear_2(y) + + return y + +mnist = Mnist() +``` + +### 模型训练 + +#### 使用高层API + +增加了paddle.Model高层API,大部分任务可以使用此API用于简化训练、评估、预测类代码开发。注意区别Model和Net概念,Net是指继承paddle.nn.Layer的网络结构;而Model是指持有一个Net实例,同时指定损失函数、优化算法、评估指标的可训练、评估、预测的实例。具体参考高层API的代码示例。 + +```python +import paddle +paddle.disable_static() + +train_dataset = paddle.vision.datasets.MNIST(mode='train') +test_dataset = paddle.vision.datasets.MNIST(mode='test') +lenet = paddle.vision.models.LeNet() + +# Mnist继承paddle.nn.Layer属于Net,model包含了训练功能 +model = paddle.Model(lenet) + +# 设置训练模型所需的optimizer, loss, metric +model.prepare( + paddle.optimizer.Adam(learning_rate=0.001, parameters=model.parameters()), + paddle.nn.CrossEntropyLoss(), + paddle.metric.Accuracy(topk=(1, 2)) + ) + +# 启动训练 +model.fit(train_dataset, epochs=2, batch_size=64, log_freq=200) + +# 启动评估 +model.evaluate(test_dataset, log_freq=20, batch_size=64) +``` + +#### 使用基础API + +```python +import paddle + +paddle.disable_static() +train_dataset = paddle.vision.datasets.MNIST(mode='train') +test_dataset = paddle.vision.datasets.MNIST(mode='test') +lenet = paddle.vision.models.LeNet() + +# 加载训练集 batch_size 设为 64 +train_loader = paddle.io.DataLoader(train_dataset, places=paddle.CPUPlace(), batch_size=64, shuffle=True) + +def train(): + epochs = 2 + adam = paddle.optimizer.Adam(learning_rate=0.001, parameters=lenet.parameters()) + # 用Adam作为优化函数 + for epoch in range(epochs): + for batch_id, data in enumerate(train_loader()): + x_data, y_data = data + predicts = lenet(x_data) + loss = paddle.nn.functional.cross_entropy(predicts, y_data, reduction='mean') + acc = paddle.metric.accuracy(predicts, y_data, k=1) + avg_acc = paddle.mean(acc) + loss.backward() + if batch_id % 100 == 0: + print("epoch: {}, batch_id: {}, loss is: {}, acc is: {}".format(epoch, batch_id, loss.numpy(), avg_acc.numpy())) + adam.step() + adam.clear_grad() +# 启动训练 +train() +``` + +### 单机多卡启动 +2.0增加paddle.distributed.spawn函数来启动单机多卡训练,同时原有的paddle.distributed.launch的方式依然保留。 + +#### 方式1、launch启动 + +##### 高层API场景 + +当调用paddle.Model高层来实现训练时,想要启动单机多卡训练非常简单,代码不需要做任何修改,只需要在启动时增加一下参数`-m paddle.distributed.launch`。 + +```bash +# 单机单卡启动,默认使用第0号卡 +$ python train.py + +# 单机多卡启动,默认使用当前可见的所有卡 +$ python -m paddle.distributed.launch train.py + +# 单机多卡启动,设置当前使用的第0号和第1号卡 +$ python -m paddle.distributed.launch --selected_gpus='0,1' train.py + +# 单机多卡启动,设置当前使用第0号和第1号卡 +$ export CUDA_VISIABLE_DEVICES='0,1' +$ python -m paddle.distributed.launch train.py +``` + +##### 基础API场景 + +如果使用基础API实现训练,想要启动单机多卡训练,需要对单机单卡的代码进行4处修改,具体如下: + +```python +import paddle +import paddle.distributed as dist + +paddle.disable_static() +train_dataset = paddle.vision.datasets.MNIST(mode='train') +test_dataset = paddle.vision.datasets.MNIST(mode='test') + +# 加载训练集 batch_size 设为 64 +train_loader = paddle.io.DataLoader(train_dataset, places=paddle.CPUPlace(), batch_size=64, shuffle=True) + +def train(): + # 第1处改动,初始化并行环境 + dist.init_parallel_env() + + # 第2处改动,增加paddle.DataParallel封装 + net = paddle.DataParallel(LeNet()) + epochs = 2 + adam = paddle.optimizer.Adam(learning_rate=0.001, parameters=net.parameters()) + # 用Adam作为优化函数 + for epoch in range(epochs): + for batch_id, data in enumerate(train_loader()): + x_data = data[0] + y_data = data[1] + predicts = net(x_data) acc = paddle.metric.accuracy(predicts, y_data, k=2) + avg_acc = paddle.mean(acc) + loss = paddle.nn.functional.cross_entropy(predicts, y_data) + + # 第3处改动,归一化loss + avg_loss = net.scale_loss(avg_loss) + avg_loss.backward() + # 第4处改动,同步梯度 + net.apply_collective_grads() + if batch_id % 100 == 0: + print("epoch: {}, batch_id: {}, loss is: {}, acc is: {}".format(epoch, batch_id, avg_loss.numpy(), avg_acc.numpy())) + adam.step() + adam.clear_grad() + +# 启动训练 +train() +``` + +修改完后保存文件,然后使用跟高层API相同的启动方式即可 + +```bash +# 单机单卡启动,默认使用第0号卡 +$ python train.py + +# 单机多卡启动,默认使用当前可见的所有卡 +$ python -m paddle.distributed.launch train.py + +# 单机多卡启动,设置当前使用的第0号和第1号卡 +$ python -m paddle.distributed.launch --selected_gpus '0,1' train.py + +# 单机多卡启动,设置当前使用第0号和第1号卡 +$ export CUDA_VISIABLE_DEVICES='0,1' +$ python -m paddle.distributed.launch train.py +``` + +#### 方式2、spawn启动 + +launch方式启动训练,以文件为单位启动多进程,需要用户在启动时调用`paddle.distributed.launch`,对于进程的管理要求较高。2.0版本增加了spawn启动方式,可以更好地控制进程,在日志打印、训练退出时更友好。 + +```bash +# 启动train多进程训练,默认使用所有可见的GPU卡 +if __name__ == '__main__': + dist.spawn(train) + +# 启动train函数2个进程训练,默认使用当前可见的前2张卡 +if __name__ == '__main__': + dist.spawn(train, nprocs=2) + +# 启动train函数2个进程训练,默认使用第4号和第5号卡 +if __name__ == '__main__': + dist.spawn(train, nprocs=2, selelcted_gpus='4,5') +``` + +### 模型保存 +Paddle保存的模型有两种格式,一种是训练格式,保存模型参数和优化器相关的状态,可用于恢复训练;一种是预测格式,保存预测的静态图网络结构以及参数,用于预测部署。 +#### 高层API场景 + +高层API下用于预测部署的模型保存方法为: + +```python +model = paddle.Model(Mnist()) +# 预测格式,保存的模型可用于预测部署 +model.save('mnist', training=False) +# 保存后可以得到预测部署所需要的模型 +``` + +#### 基础API场景 + +动态图训练的模型,可以通过动静转换功能,转换为可部署的静态图模型,具体做法如下: + +```python +import paddle +from paddle.jit import to_static +from paddle.static import InputSpec + +class SimpleNet(paddle.nn.Layer): + def __init__(self): + super(SimpleNet, self).__init__() + self.linear = paddle.nn.Linear(10, 3) + + # 第1处改动 + # 通过InputSpec指定输入数据的形状,None表示可变长 + # 通过to_static装饰器将动态图转换为静态图Program + @to_static(input_spec=[InputSpec(shape=[None, 10], name='x'), InputSpec(shape=[3], name='y')]) + def forward(self, x, y): + out = self.linear(x) + out = out + y + return out + +paddle.disable_static() + +net = SimpleNet() + +# 第2处改动 +# 保存静态图模型,可用于预测部署 +paddle.jit.save(net, './simple_net') +``` +### 推理 +推理库Paddle Inference的API做了升级,简化了写法,以及去掉了历史上冗余的概念。API的变化为纯增,原有API保持不变,但推荐新的API体系,旧API在后续版本会逐步删除。 + +#### C++ API + +重要变化: + +- 命名空间从 `paddle` 变更为 `paddle_infer` +- `PaddleTensor`, `PaddleBuf` 等被废弃,`ZeroCopyTensor` 变为默认 Tensor 类型,并更名为 `Tensor` +- 新增 `PredictorPool` 工具类简化多线程 predictor 的创建,后续也会增加更多周边工具 +- `CreatePredictor` (原 `CreatePaddlePredictor`) 的返回值由 `unique_ptr` 变为 `shared_ptr` 以避免 Clone 后析构顺序出错的问题 + +API 变更 + +| 原有命名 | 现有命名 | 行为变化 | +| ---------------------------- | ---------------------------- | ----------------------------- | +| 头文件 `paddle_infer.h` | 无变化 | 包含旧接口,保持向后兼容 | +| 无 | `paddle_inference_api.h` | 新API,可以与旧接口并存 | +| `CreatePaddlePredictor` | `CreatePredictor` | 返回值变为 shared_ptr | +| `ZeroCopyTensor` | `Tensor` | 无 | +| `AnalysisConfig` | `Config` | 无 | +| `TensorRTConfig` | 废弃 | | +| `PaddleTensor` + `PaddleBuf` | 废弃 | | +| `Predictor::GetInputTensor` | `Predictor::GetInputHandle` | 无 | +| `Predictor::GetOutputTensor` | `Predictor::GetOutputHandle` | 无 | +| | `PredictorPool` | 简化创建多个 predictor 的支持 | + +使用新 C++ API 的流程与之前完全一致,只有命名变化 + +```c++ +#include "paddle_infernce_api.h" +using namespace paddle_infer; + +Config config; +config.SetModel("xxx_model_dir"); + +auto predictor = CreatePredictor(config); + +// Get the handles for the inputs and outputs of the model +auto input0 = predictor->GetInputHandle("X"); +auto output0 = predictor->GetOutputHandle("Out"); + +for (...) { + // Assign data to input0 + MyServiceSetData(input0); + + predictor->Run(); + + // get data from the output0 handle + MyServiceGetData(output0); +} +``` + +#### Python API + +Python API 的变更与 C++ 基本对应,会在2.0RC版发布。 + + +## 附录 +### 2.0转换工具 +为了降级代码升级的成本,我们提供了转换工具,可以帮助将Paddle 1.8版本开发的代码,升级为2.0-beta的API。由于相比于Paddle 1.8版本,2.0-beta版本的API进行了大量的升级,包括API名称,参数名称,行为等。转换工具当前还不能覆盖所有的API升级;对于无法转换的API,转换工具会报错,提示用户手动升级。 + +https://github.com/PaddlePaddle/paddle1to2 + +对于转换工具没有覆盖的API,请查看官网的API文档,手动升级代码的API。 + +### 2.0文档教程 +以下提供了2.0版本的一些示例教程: + +您可以在官网[应用实践](https://www.paddlepaddle.org.cn/documentation/docs/zh/2.0-beta/tutorial/index_cn.html)栏目内进行在线浏览,也可以下载在这里提供的源代码: +https://github.com/PaddlePaddle/book/tree/develop/paddle2.0_docs + +### 2.0API升级列表 +- [Release Note](https://github.com/PaddlePaddle/Paddle/releases/tag/v2.0.0-beta0#) +- [API新增列表](https://github.com/PaddlePaddle/Paddle/wiki/Paddle-2.0beta-New-API-List) +- [API升级列表](https://github.com/PaddlePaddle/Paddle/wiki/Paddle-2.0beta-Upgraded-API-List) diff --git a/doc/paddle/tutorial/cv_case/image_segmentation/pets_image_segmentation_U_Net_like.ipynb b/doc/paddle/tutorial/cv_case/image_segmentation/pets_image_segmentation_U_Net_like.ipynb index 9dd56ed42fb192d5bd9309c6aa64901e508c7214..e731144601952d278a305cb0597da2137b0fe5cc 100644 --- a/doc/paddle/tutorial/cv_case/image_segmentation/pets_image_segmentation_U_Net_like.ipynb +++ b/doc/paddle/tutorial/cv_case/image_segmentation/pets_image_segmentation_U_Net_like.ipynb @@ -34,7 +34,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 1, "metadata": {}, "outputs": [ { @@ -43,7 +43,7 @@ "'2.0.0-beta0'" ] }, - "execution_count": 21, + "execution_count": 1, "metadata": {}, "output_type": "execute_result" } @@ -58,6 +58,9 @@ "import paddle\n", "from paddle.nn import functional as F\n", "\n", + "device = paddle.set_device('gpu')\n", + "paddle.disable_static(device)\n", + "\n", "paddle.__version__" ] }, @@ -173,7 +176,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 2, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -235,7 +238,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -388,7 +391,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 4, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -464,7 +467,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 5, "metadata": { "colab": {}, "colab_type": "code", @@ -527,7 +530,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 6, "metadata": { "colab": {}, "colab_type": "code", @@ -587,7 +590,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 7, "metadata": { "colab": {}, "colab_type": "code", @@ -648,7 +651,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 8, "metadata": { "colab": {}, "colab_type": "code", @@ -724,7 +727,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 9, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -743,28 +746,28 @@ "--------------------------------------------------------------------------------\n", " Layer (type) Input Shape Output Shape Param #\n", "================================================================================\n", - " Conv2d-38 [-1, 3, 160, 160] [-1, 32, 80, 80] 896\n", - " BatchNorm2d-14 [-1, 32, 80, 80] [-1, 32, 80, 80] 128\n", - " ReLU-14 [-1, 32, 80, 80] [-1, 32, 80, 80] 0\n", - " ReLU-17 [-1, 256, 20, 20] [-1, 256, 20, 20] 0\n", - " Conv2d-49 [-1, 128, 20, 20] [-1, 128, 20, 20] 1,152\n", - " Conv2d-50 [-1, 128, 20, 20] [-1, 256, 20, 20] 33,024\n", - "SeparableConv2d-17 [-1, 128, 20, 20] [-1, 256, 20, 20] 0\n", - " BatchNorm2d-17 [-1, 256, 20, 20] [-1, 256, 20, 20] 1,024\n", - " Conv2d-51 [-1, 256, 20, 20] [-1, 256, 20, 20] 2,304\n", - " Conv2d-52 [-1, 256, 20, 20] [-1, 256, 20, 20] 65,792\n", - "SeparableConv2d-18 [-1, 256, 20, 20] [-1, 256, 20, 20] 0\n", - " MaxPool2d-9 [-1, 256, 20, 20] [-1, 256, 10, 10] 0\n", - " Conv2d-53 [-1, 128, 20, 20] [-1, 256, 10, 10] 33,024\n", - " Encoder-9 [-1, 128, 20, 20] [-1, 256, 10, 10] 0\n", - " ReLU-21 [-1, 32, 80, 80] [-1, 32, 80, 80] 0\n", - "ConvTranspose2d-17 [-1, 64, 80, 80] [-1, 32, 80, 80] 18,464\n", - " BatchNorm2d-21 [-1, 32, 80, 80] [-1, 32, 80, 80] 128\n", - "ConvTranspose2d-18 [-1, 32, 80, 80] [-1, 32, 80, 80] 9,248\n", - " Upsample-8 [-1, 64, 80, 80] [-1, 64, 160, 160] 0\n", - " Conv2d-57 [-1, 64, 160, 160] [-1, 32, 160, 160] 2,080\n", - " Decoder-9 [-1, 64, 80, 80] [-1, 32, 160, 160] 0\n", - " Conv2d-58 [-1, 32, 160, 160] [-1, 4, 160, 160] 1,156\n", + " Conv2d-1 [-1, 3, 160, 160] [-1, 32, 80, 80] 896\n", + " BatchNorm2d-1 [-1, 32, 80, 80] [-1, 32, 80, 80] 128\n", + " ReLU-1 [-1, 32, 80, 80] [-1, 32, 80, 80] 0\n", + " ReLU-4 [-1, 256, 20, 20] [-1, 256, 20, 20] 0\n", + " Conv2d-12 [-1, 128, 20, 20] [-1, 128, 20, 20] 1,152\n", + " Conv2d-13 [-1, 128, 20, 20] [-1, 256, 20, 20] 33,024\n", + "SeparableConv2d-5 [-1, 128, 20, 20] [-1, 256, 20, 20] 0\n", + " BatchNorm2d-4 [-1, 256, 20, 20] [-1, 256, 20, 20] 1,024\n", + " Conv2d-14 [-1, 256, 20, 20] [-1, 256, 20, 20] 2,304\n", + " Conv2d-15 [-1, 256, 20, 20] [-1, 256, 20, 20] 65,792\n", + "SeparableConv2d-6 [-1, 256, 20, 20] [-1, 256, 20, 20] 0\n", + " MaxPool2d-3 [-1, 256, 20, 20] [-1, 256, 10, 10] 0\n", + " Conv2d-16 [-1, 128, 20, 20] [-1, 256, 10, 10] 33,024\n", + " Encoder-3 [-1, 128, 20, 20] [-1, 256, 10, 10] 0\n", + " ReLU-8 [-1, 32, 80, 80] [-1, 32, 80, 80] 0\n", + "ConvTranspose2d-7 [-1, 64, 80, 80] [-1, 32, 80, 80] 18,464\n", + " BatchNorm2d-8 [-1, 32, 80, 80] [-1, 32, 80, 80] 128\n", + "ConvTranspose2d-8 [-1, 32, 80, 80] [-1, 32, 80, 80] 9,248\n", + " Upsample-4 [-1, 64, 80, 80] [-1, 64, 160, 160] 0\n", + " Conv2d-20 [-1, 64, 160, 160] [-1, 32, 160, 160] 2,080\n", + " Decoder-4 [-1, 64, 80, 80] [-1, 32, 160, 160] 0\n", + " Conv2d-21 [-1, 32, 160, 160] [-1, 4, 160, 160] 1,156\n", "================================================================================\n", "Total params: 168,420\n", "Trainable params: 167,140\n", @@ -784,7 +787,7 @@ "{'total_params': 168420, 'trainable_params': 167140}" ] }, - "execution_count": 31, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -808,34 +811,6 @@ "## 5.模型训练" ] }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "8Sskbyz58X4J" - }, - "source": [ - "### 5.1 配置信息\n", - "\n", - "定义训练BATCH_SIZE、训练轮次和计算设备等信息。" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "4fSkTiRB8OpP" - }, - "outputs": [], - "source": [ - "BATCH_SIZE = 32\n", - "EPOCHS = 15\n", - "device = paddle.set_device('gpu')\n", - "paddle.disable_static(device)" - ] - }, { "cell_type": "markdown", "metadata": { @@ -843,14 +818,14 @@ "id": "x_vaedRa8eoy" }, "source": [ - "### 5.3 自定义Loss\n", + "### 5.1 自定义Loss\n", "\n", "在这个任务中我们使用SoftmaxWithCrossEntropy损失函数来做计算,飞桨中有functional形式的API,这里我们做一个自定义操作,实现一个Class形式API放到模型训练中使用。没有直接使用CrossEntropyLoss的原因主要是对计算维度的自定义需求,本次需要进行softmax计算的维度是1,不是默认的最后一维,所以我们采用上面提到的损失函数,通过axis参数来指定softmax计算维度。" ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 10, "metadata": { "colab": {}, "colab_type": "code", @@ -877,7 +852,7 @@ "id": "rj6MPPMkJIdZ" }, "source": [ - "### 5.4 启动模型训练\n", + "### 5.2 启动模型训练\n", "\n", "使用模型代码进行Model实例生成,使用prepare接口定义优化器、损失函数和评价指标等信息,用于后续训练使用。在所有初步配置完成后,调用fit接口开启训练执行过程,调用fit时只需要将前面定义好的训练数据集、测试数据集、训练轮次(Epoch)和批次大小(batch_size)配置好即可。" ] @@ -903,12 +878,12 @@ " epsilon=1e-07, \n", " centered=False,\n", " parameters=model.parameters())\n", - "model = paddle.Model(PetModel(num_classes))\n", + "model = paddle.Model(PetNet(num_classes))\n", "model.prepare(optim, SoftmaxWithCrossEntropy())\n", "model.fit(train_dataset, \n", " val_dataset, \n", - " epochs=EPOCHS, \n", - " batch_size=BATCH_SIZE)" + " epochs=15, \n", + " batch_size=32)" ] }, { diff --git a/doc/paddle/tutorial/cv_case/image_segmentation/pets_image_segmentation_U_Net_like.rst b/doc/paddle/tutorial/cv_case/image_segmentation/pets_image_segmentation_U_Net_like.rst index 7b96f98bf48859608a92272cafb92f309b37d4ec..55821cc5e3e018b9eac3dd659655ed7922af22d2 100644 --- a/doc/paddle/tutorial/cv_case/image_segmentation/pets_image_segmentation_U_Net_like.rst +++ b/doc/paddle/tutorial/cv_case/image_segmentation/pets_image_segmentation_U_Net_like.rst @@ -26,6 +26,9 @@ import paddle from paddle.nn import functional as F + device = paddle.set_device('gpu') + paddle.disable_static(device) + paddle.__version__ @@ -326,7 +329,7 @@ DataLoader(多进程数据集加载)。 -.. image:: https://github.com/PaddlePaddle/FluidDoc/blob/develop/doc/paddle/tutorial/cv_case/image_segmentation/pets_image_segmentation_U_Net_like_files/pets_image_segmentation_U_Net_like_001.png?raw=true +.. image:: https://raw.githubusercontent.com/PaddlePaddle/FluidDoc/develop/doc/paddle/tutorial/cv_case/image_segmentation/pets_image_segmentation_U_Net_like_files/pets_image_segmentation_U_Net_like_001.png 4.模型组网 @@ -551,28 +554,28 @@ Layer类,整个过程是把\ ``filter_size * filter_size * num_filters``\ 的C -------------------------------------------------------------------------------- Layer (type) Input Shape Output Shape Param # ================================================================================ - Conv2d-38 [-1, 3, 160, 160] [-1, 32, 80, 80] 896 - BatchNorm2d-14 [-1, 32, 80, 80] [-1, 32, 80, 80] 128 - ReLU-14 [-1, 32, 80, 80] [-1, 32, 80, 80] 0 - ReLU-17 [-1, 256, 20, 20] [-1, 256, 20, 20] 0 - Conv2d-49 [-1, 128, 20, 20] [-1, 128, 20, 20] 1,152 - Conv2d-50 [-1, 128, 20, 20] [-1, 256, 20, 20] 33,024 - SeparableConv2d-17 [-1, 128, 20, 20] [-1, 256, 20, 20] 0 - BatchNorm2d-17 [-1, 256, 20, 20] [-1, 256, 20, 20] 1,024 - Conv2d-51 [-1, 256, 20, 20] [-1, 256, 20, 20] 2,304 - Conv2d-52 [-1, 256, 20, 20] [-1, 256, 20, 20] 65,792 - SeparableConv2d-18 [-1, 256, 20, 20] [-1, 256, 20, 20] 0 - MaxPool2d-9 [-1, 256, 20, 20] [-1, 256, 10, 10] 0 - Conv2d-53 [-1, 128, 20, 20] [-1, 256, 10, 10] 33,024 - Encoder-9 [-1, 128, 20, 20] [-1, 256, 10, 10] 0 - ReLU-21 [-1, 32, 80, 80] [-1, 32, 80, 80] 0 - ConvTranspose2d-17 [-1, 64, 80, 80] [-1, 32, 80, 80] 18,464 - BatchNorm2d-21 [-1, 32, 80, 80] [-1, 32, 80, 80] 128 - ConvTranspose2d-18 [-1, 32, 80, 80] [-1, 32, 80, 80] 9,248 - Upsample-8 [-1, 64, 80, 80] [-1, 64, 160, 160] 0 - Conv2d-57 [-1, 64, 160, 160] [-1, 32, 160, 160] 2,080 - Decoder-9 [-1, 64, 80, 80] [-1, 32, 160, 160] 0 - Conv2d-58 [-1, 32, 160, 160] [-1, 4, 160, 160] 1,156 + Conv2d-1 [-1, 3, 160, 160] [-1, 32, 80, 80] 896 + BatchNorm2d-1 [-1, 32, 80, 80] [-1, 32, 80, 80] 128 + ReLU-1 [-1, 32, 80, 80] [-1, 32, 80, 80] 0 + ReLU-4 [-1, 256, 20, 20] [-1, 256, 20, 20] 0 + Conv2d-12 [-1, 128, 20, 20] [-1, 128, 20, 20] 1,152 + Conv2d-13 [-1, 128, 20, 20] [-1, 256, 20, 20] 33,024 + SeparableConv2d-5 [-1, 128, 20, 20] [-1, 256, 20, 20] 0 + BatchNorm2d-4 [-1, 256, 20, 20] [-1, 256, 20, 20] 1,024 + Conv2d-14 [-1, 256, 20, 20] [-1, 256, 20, 20] 2,304 + Conv2d-15 [-1, 256, 20, 20] [-1, 256, 20, 20] 65,792 + SeparableConv2d-6 [-1, 256, 20, 20] [-1, 256, 20, 20] 0 + MaxPool2d-3 [-1, 256, 20, 20] [-1, 256, 10, 10] 0 + Conv2d-16 [-1, 128, 20, 20] [-1, 256, 10, 10] 33,024 + Encoder-3 [-1, 128, 20, 20] [-1, 256, 10, 10] 0 + ReLU-8 [-1, 32, 80, 80] [-1, 32, 80, 80] 0 + ConvTranspose2d-7 [-1, 64, 80, 80] [-1, 32, 80, 80] 18,464 + BatchNorm2d-8 [-1, 32, 80, 80] [-1, 32, 80, 80] 128 + ConvTranspose2d-8 [-1, 32, 80, 80] [-1, 32, 80, 80] 9,248 + Upsample-4 [-1, 64, 80, 80] [-1, 64, 160, 160] 0 + Conv2d-20 [-1, 64, 160, 160] [-1, 32, 160, 160] 2,080 + Decoder-4 [-1, 64, 80, 80] [-1, 32, 160, 160] 0 + Conv2d-21 [-1, 32, 160, 160] [-1, 4, 160, 160] 1,156 ================================================================================ Total params: 168,420 Trainable params: 167,140 @@ -597,19 +600,7 @@ Layer类,整个过程是把\ ``filter_size * filter_size * num_filters``\ 的C 5.模型训练 ---------- -5.1 配置信息 -~~~~~~~~~~~~ - -定义训练BATCH_SIZE、训练轮次和计算设备等信息。 - -.. code:: ipython3 - - BATCH_SIZE = 32 - EPOCHS = 15 - device = paddle.set_device('gpu') - paddle.disable_static(device) - -5.3 自定义Loss +5.1 自定义Loss ~~~~~~~~~~~~~~ 在这个任务中我们使用SoftmaxWithCrossEntropy损失函数来做计算,飞桨中有functional形式的API,这里我们做一个自定义操作,实现一个Class形式API放到模型训练中使用。没有直接使用CrossEntropyLoss的原因主要是对计算维度的自定义需求,本次需要进行softmax计算的维度是1,不是默认的最后一维,所以我们采用上面提到的损失函数,通过axis参数来指定softmax计算维度。 @@ -627,7 +618,7 @@ Layer类,整个过程是把\ ``filter_size * filter_size * num_filters``\ 的C axis=1) return paddle.mean(loss) -5.4 启动模型训练 +5.2 启动模型训练 ~~~~~~~~~~~~~~~~ 使用模型代码进行Model实例生成,使用prepare接口定义优化器、损失函数和评价指标等信息,用于后续训练使用。在所有初步配置完成后,调用fit接口开启训练执行过程,调用fit时只需要将前面定义好的训练数据集、测试数据集、训练轮次(Epoch)和批次大小(batch_size)配置好即可。 @@ -640,12 +631,12 @@ Layer类,整个过程是把\ ``filter_size * filter_size * num_filters``\ 的C epsilon=1e-07, centered=False, parameters=model.parameters()) - model = paddle.Model(PetModel(num_classes)) + model = paddle.Model(PetNet(num_classes)) model.prepare(optim, SoftmaxWithCrossEntropy()) model.fit(train_dataset, val_dataset, - epochs=EPOCHS, - batch_size=BATCH_SIZE) + epochs=15, + batch_size=32) 6.模型预测 ---------- diff --git a/doc/paddle/tutorial/quick_start/getting_started/getting_started.ipynb b/doc/paddle/tutorial/quick_start/getting_started/getting_started.ipynb index 33b2afdc358a11006a32e47766c3341d94894920..fc646cd4e15771d75f12cd725bba2b5dd78cab51 100644 --- a/doc/paddle/tutorial/quick_start/getting_started/getting_started.ipynb +++ b/doc/paddle/tutorial/quick_start/getting_started/getting_started.ipynb @@ -31,24 +31,22 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 8, "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "'2.0.0-beta0'" - ] - }, - "execution_count": 1, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "2.0.0-beta0\n" + ] } ], "source": [ "import paddle\n", "\n", - "paddle.__version__" + "print(paddle.__version__)\n", + "paddle.disable_static()" ] }, { @@ -71,7 +69,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -90,7 +88,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -113,7 +111,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 11, "metadata": { "scrolled": true }, @@ -123,15 +121,15 @@ "output_type": "stream", "text": [ "Epoch 1/5\n", - "step 1875/1875 [==============================] - loss: 0.2571 - acc: 0.9037 - 10ms/step \n", + "step 1875/1875 [==============================] - loss: 0.2250 - acc: 0.9025 - 9ms/step \n", "Epoch 2/5\n", - "step 1875/1875 [==============================] - loss: 0.1880 - acc: 0.9458 - 14ms/step \n", + "step 1875/1875 [==============================] - loss: 0.0969 - acc: 0.9462 - 13ms/step \n", "Epoch 3/5\n", - "step 1875/1875 [==============================] - loss: 0.0279 - acc: 0.9549 - 11ms/step \n", + "step 1875/1875 [==============================] - loss: 0.1035 - acc: 0.9550 - 12ms/step \n", "Epoch 4/5\n", - "step 1875/1875 [==============================] - loss: 0.0505 - acc: 0.9608 - 13ms/step \n", + "step 1875/1875 [==============================] - loss: 0.0316 - acc: 0.9603 - 12ms/step \n", "Epoch 5/5\n", - "step 1875/1875 [==============================] - loss: 0.2253 - acc: 0.9646 - 12ms/step \n" + "step 1875/1875 [==============================] - loss: 0.1771 - acc: 0.9637 - 12ms/step \n" ] } ], @@ -189,9 +187,7 @@ "source": [ "那么初步训练得到的模型效果在97%附近,我们可以进一步通过调整其中的训练参数来提升我们的模型精度。\n", "\n", - "至此我们可以知道如何通过飞桨的几个简单API来快速完成一个深度学习任务,大家可以针对自己的需求来更换其中的代码,如果需要使用自己的数据集,那么可以更换数据集加载部分程序,如果需要替换模型,那么可以更改模型代码实现等等。我们也为大家提供了很多其他场景的示例代码来教大家如何使用我们的飞桨API,大家可以查看下面的链接或通过页面导航来查看自己感兴趣的部分。\n", - "\n", - "TODO:补充其他示例教程的快速链接。" + "至此我们可以知道如何通过飞桨的几个简单API来快速完成一个深度学习任务,大家可以针对自己的需求来更换其中的代码,如果需要使用自己的数据集,那么可以更换数据集加载部分程序,如果需要替换模型,那么可以更改模型代码实现等等。我们也为大家提供了很多其他场景的示例代码来教大家如何使用我们的飞桨API,大家可以查看下面的链接或通过页面导航来查看自己感兴趣的部分。" ] } ], diff --git a/doc/paddle/tutorial/quick_start/getting_started/getting_started.rst b/doc/paddle/tutorial/quick_start/getting_started/getting_started.rst index f77bc038dcbe5a2ff86fca3eb539109808c08182..72a65373a121d193d567538839975204988502e3 100644 --- a/doc/paddle/tutorial/quick_start/getting_started/getting_started.rst +++ b/doc/paddle/tutorial/quick_start/getting_started/getting_started.rst @@ -19,15 +19,13 @@ import paddle - paddle.__version__ - - + print(paddle.__version__) + paddle.disable_static() .. parsed-literal:: - '2.0.0-beta0' - + 2.0.0-beta0 3. 实践一个手写数字识别任务 @@ -91,15 +89,15 @@ .. parsed-literal:: Epoch 1/5 - step 1875/1875 [==============================] - loss: 0.2571 - acc: 0.9037 - 10ms/step + step 1875/1875 [==============================] - loss: 0.2250 - acc: 0.9025 - 9ms/step Epoch 2/5 - step 1875/1875 [==============================] - loss: 0.1880 - acc: 0.9458 - 14ms/step + step 1875/1875 [==============================] - loss: 0.0969 - acc: 0.9462 - 13ms/step Epoch 3/5 - step 1875/1875 [==============================] - loss: 0.0279 - acc: 0.9549 - 11ms/step + step 1875/1875 [==============================] - loss: 0.1035 - acc: 0.9550 - 12ms/step Epoch 4/5 - step 1875/1875 [==============================] - loss: 0.0505 - acc: 0.9608 - 13ms/step + step 1875/1875 [==============================] - loss: 0.0316 - acc: 0.9603 - 12ms/step Epoch 5/5 - step 1875/1875 [==============================] - loss: 0.2253 - acc: 0.9646 - 12ms/step + step 1875/1875 [==============================] - loss: 0.1771 - acc: 0.9637 - 12ms/step 3.4 模型评估 diff --git a/doc/paddle/tutorial/quick_start/high_level_api/high_level_api.ipynb b/doc/paddle/tutorial/quick_start/high_level_api/high_level_api.ipynb index feeb7068ee718b97632546f2e6af1dcfe5b6878b..7fdef0b264743b671b7d7a2712852b7658272309 100644 --- a/doc/paddle/tutorial/quick_start/high_level_api/high_level_api.ipynb +++ b/doc/paddle/tutorial/quick_start/high_level_api/high_level_api.ipynb @@ -8,7 +8,7 @@ "\n", "## 1. 简介\n", "\n", - "飞桨2.0全新推出高层API,是对飞桨API的进一步封装与升级,提供了更加简洁易用的API,进一步提升了飞桨的易学易用性,并增强飞桨的功能。\n", + "飞桨框架2.0全新推出高层API,是对飞桨API的进一步封装与升级,提供了更加简洁易用的API,进一步提升了飞桨的易学易用性,并增强飞桨的功能。\n", "\n", "飞桨高层API面向从深度学习小白到资深开发者的所有人群,对于AI初学者来说,使用高层API可以简单快速的构建深度学习项目,对于资深开发者来说,可以快速完成算法迭代。\n", "\n", @@ -36,7 +36,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -45,7 +45,7 @@ "'2.0.0-beta0'" ] }, - "execution_count": 1, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } @@ -55,6 +55,9 @@ "import paddle.vision as vision\n", "import paddle.text as text\n", "\n", + "# 启动动态图训练模式\n", + "paddle.disable_static()\n", + "\n", "paddle.__version__" ] }, @@ -90,7 +93,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "metadata": { "tags": [] }, @@ -100,7 +103,7 @@ "output_type": "stream", "text": [ "视觉相关数据集: ['DatasetFolder', 'ImageFolder', 'MNIST', 'Flowers', 'Cifar10', 'Cifar100', 'VOC2012']\n", - "自然语言相关数据集: ['Conll05st', 'Imdb', 'Imikolov', 'Movielens', 'MovieReviews', 'UCIHousing', 'WMT14', 'WMT16']\n" + "自然语言相关数据集: ['Conll05st', 'Imdb', 'Imikolov', 'Movielens', 'UCIHousing', 'WMT14', 'WMT16']\n" ] } ], @@ -118,7 +121,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -140,7 +143,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 5, "metadata": { "tags": [] }, @@ -207,8 +210,8 @@ " return len(self.data)\n", "\n", "# 测试定义的数据集\n", - "train_dataset = MyDataset(mode='train')\n", - "val_dataset = MyDataset(mode='test')\n", + "train_dataset_2 = MyDataset(mode='train')\n", + "val_dataset_2 = MyDataset(mode='test')\n", "\n", "print('=============train dataset=============')\n", "for data, label in train_dataset:\n", @@ -232,7 +235,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -243,7 +246,7 @@ "transform = Compose([ColorJitter(), Resize(size=100)])\n", "\n", "# 通过transform参数传递定义好的数据增项方法即可完成对自带数据集的应用\n", - "train_dataset = vision.datasets.MNIST(mode='train', transform=transform)" + "train_dataset_3 = vision.datasets.MNIST(mode='train', transform=transform)" ] }, { @@ -257,7 +260,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -316,7 +319,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -340,7 +343,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 31, "metadata": {}, "outputs": [], "source": [ @@ -364,7 +367,7 @@ "\n", " return y\n", "\n", - "mnist = Mnist()" + "mnist_2 = Mnist()" ] }, { @@ -380,14 +383,12 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 32, "metadata": {}, "outputs": [], "source": [ "# 场景1:动态图模式\n", "\n", - "# 启动动态图训练模式\n", - "paddle.disable_static()\n", "# 使用GPU训练\n", "paddle.set_device('gpu')\n", "# 模型封装\n", @@ -412,9 +413,45 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 33, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--------------------------------------------------------------------------------\n", + " Layer (type) Input Shape Output Shape Param #\n", + "================================================================================\n", + " Flatten-57509 [-1, 1, 28, 28] [-1, 784] 0\n", + " Linear-7 [-1, 784] [-1, 512] 401,920\n", + " ReLU-4 [-1, 512] [-1, 512] 0\n", + " Dropout-4 [-1, 512] [-1, 512] 0\n", + " Linear-8 [-1, 512] [-1, 10] 5,130\n", + "================================================================================\n", + "Total params: 407,050\n", + "Trainable params: 407,050\n", + "Non-trainable params: 0\n", + "--------------------------------------------------------------------------------\n", + "Input size (MB): 0.00\n", + "Forward/backward pass size (MB): 0.02\n", + "Params size (MB): 1.55\n", + "Estimated Total Size (MB): 1.57\n", + "--------------------------------------------------------------------------------\n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "{'total_params': 407050, 'trainable_params': 407050}" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "model.summary((1, 28, 28))" ] @@ -428,9 +465,45 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 34, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--------------------------------------------------------------------------------\n", + " Layer (type) Input Shape Output Shape Param #\n", + "================================================================================\n", + " Flatten-57508 [-1, 1, 28, 28] [-1, 784] 0\n", + " Linear-5 [-1, 784] [-1, 512] 401,920\n", + " ReLU-3 [-1, 512] [-1, 512] 0\n", + " Dropout-3 [-1, 512] [-1, 512] 0\n", + " Linear-6 [-1, 512] [-1, 10] 5,130\n", + "================================================================================\n", + "Total params: 407,050\n", + "Trainable params: 407,050\n", + "Non-trainable params: 0\n", + "--------------------------------------------------------------------------------\n", + "Input size (MB): 0.00\n", + "Forward/backward pass size (MB): 0.02\n", + "Params size (MB): 1.55\n", + "Estimated Total Size (MB): 1.57\n", + "--------------------------------------------------------------------------------\n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "{'total_params': 407050, 'trainable_params': 407050}" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "paddle.summary(mnist, (1, 28, 28))" ] @@ -456,7 +529,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 35, "metadata": {}, "outputs": [], "source": [ @@ -475,9 +548,36 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 36, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 1/10\n", + "step 1875/1875 [==============================] - loss: 0.1600 - acc: 0.9022 - 10ms/step \n", + "Epoch 2/10\n", + "step 1875/1875 [==============================] - loss: 0.0455 - acc: 0.9461 - 12ms/step \n", + "Epoch 3/10\n", + "step 1875/1875 [==============================] - loss: 0.1429 - acc: 0.9544 - 19ms/step \n", + "Epoch 4/10\n", + "step 1875/1875 [==============================] - loss: 0.0197 - acc: 0.9601 - 22ms/step \n", + "Epoch 5/10\n", + "step 1875/1875 [==============================] - loss: 0.1762 - acc: 0.9644 - 25ms/step \n", + "Epoch 6/10\n", + "step 1875/1875 [==============================] - loss: 0.1304 - acc: 0.9667 - 22ms/step \n", + "Epoch 7/10\n", + "step 1875/1875 [==============================] - loss: 0.0133 - acc: 0.9682 - 22ms/step \n", + "Epoch 8/10\n", + "step 1875/1875 [==============================] - loss: 0.0097 - acc: 0.9705 - 19ms/step \n", + "Epoch 9/10\n", + "step 1875/1875 [==============================] - loss: 3.1264e-04 - acc: 0.9716 - 23ms/step \n", + "Epoch 10/10\n", + "step 1875/1875 [==============================] - loss: 0.0767 - acc: 0.9729 - 13ms/step \n" + ] + } + ], "source": [ "# 启动模型训练,指定训练数据集,设置训练轮次,设置每次数据集计算的批次大小,设置日志格式\n", "model.fit(train_dataset, \n", @@ -497,14 +597,39 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 20, "metadata": { "tags": [] }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 1/10\n", + "step 1875/1875 [==============================] - loss: 0.0490 - acc: 0.9741 - 6ms/step \n", + "Epoch 2/10\n", + "step 1875/1875 [==============================] - loss: 0.1384 - acc: 0.9760 - 7ms/step \n", + "Epoch 3/10\n", + "step 1875/1875 [==============================] - loss: 0.0929 - acc: 0.9767 - 7ms/step \n", + "Epoch 4/10\n", + "step 1875/1875 [==============================] - loss: 0.0190 - acc: 0.9772 - 6ms/step \n", + "Epoch 5/10\n", + "step 1875/1875 [==============================] - loss: 0.0862 - acc: 0.9774 - 7ms/step \n", + "Epoch 6/10\n", + "step 1875/1875 [==============================] - loss: 0.0748 - acc: 0.9785 - 8ms/step \n", + "Epoch 7/10\n", + "step 1875/1875 [==============================] - loss: 0.0039 - acc: 0.9798 - 17ms/step \n", + "Epoch 8/10\n", + "step 1875/1875 [==============================] - loss: 0.0037 - acc: 0.9808 - 11ms/step \n", + "Epoch 9/10\n", + "step 1875/1875 [==============================] - loss: 0.0013 - acc: 0.9800 - 8ms/step \n", + "Epoch 10/10\n", + "step 1875/1875 [==============================] - loss: 0.0376 - acc: 0.9810 - 8ms/step \n" + ] + } + ], "source": [ - "# 启动动态图训练模式\n", - "paddle.disable_static()\n", "\n", "# 使用GPU训练\n", "paddle.set_device('gpu')\n", @@ -530,17 +655,13 @@ "source": [ "### 5.2 单机多卡\n", "\n", - "对于高层API来实现单机多卡非常简单,整个训练代码和单机单卡没有差异。直接使用`paddle.distributed.launch`启动单机单卡的程序即可。" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# train.py里面包含的就是单机单卡代码\n", - "python -m paddle.distributed.launch train.py" + "对于高层API来实现单机多卡非常简单,整个训练代码和单机单卡没有差异。直接使用`paddle.distributed.launch`启动单机单卡的程序即可。\n", + "\n", + "```bash\n", + "$ python -m paddle.distributed.launch train.py\n", + "```\n", + "\n", + "train.py里面包含的就是单机单卡代码" ] }, { @@ -810,9 +931,19 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Eval begin...\n", + "step 10000/10000 [==============================] - loss: 0.0000e+00 - acc: 0.9801 - 2ms/step \n", + "Eval samples: 10000\n" + ] + } + ], "source": [ "result = model.evaluate(val_dataset, verbose=1)" ] @@ -834,9 +965,19 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 22, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Predict begin...\n", + "step 10000/10000 [==============================] - 4ms/step \n", + "Predict samples: 10000\n" + ] + } + ], "source": [ "pred_result = model.predict(val_dataset)" ] @@ -866,17 +1007,40 @@ "\n", "### 8.1 模型存储\n", "\n", - "模型训练和验证达到我们的预期后,可以使用`save`接口来将我们的模型保存下来,用于后续模型的Fine-tuning(接口参数training=True)或推理部署(接口参数training=False)。" + "模型训练和验证达到我们的预期后,可以使用`save`接口来将我们的模型保存下来,用于后续模型的Fine-tuning(接口参数training=True)或推理部署(接口参数training=False)。\n", + "\n", + "需要注意的是,在动态图模式训练时保存推理模型的参数文件和模型文件,需要在forward成员函数上添加@paddle.jit.to_static装饰器,参考下面的例子:\n", + "\n", + "```python\n", + "class Mnist(paddle.nn.Layer):\n", + " def __init__(self):\n", + " super(Mnist, self).__init__()\n", + "\n", + " self.flatten = paddle.nn.Flatten()\n", + " self.linear_1 = paddle.nn.Linear(784, 512)\n", + " self.linear_2 = paddle.nn.Linear(512, 10)\n", + " self.relu = paddle.nn.ReLU()\n", + " self.dropout = paddle.nn.Dropout(0.2)\n", + "\n", + " @paddle.jit.to_static\n", + " def forward(self, inputs):\n", + " y = self.flatten(inputs)\n", + " y = self.linear_1(y)\n", + " y = self.relu(y)\n", + " y = self.dropout(y)\n", + " y = self.linear_2(y)\n", + "\n", + " return y\n", + "```" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ - "# 保存用于推理部署的模型(training=False)\n", - "model.save('~/model/mnist', training=False)" + "model.save('~/model/mnist')" ] }, { diff --git a/doc/paddle/tutorial/quick_start/high_level_api/high_level_api.rst b/doc/paddle/tutorial/quick_start/high_level_api/high_level_api.rst index 3359926c541f34d0533b0971332854f5271a179e..8f776df2bbf4648272171f8b7a72f2eb7ba20714 100644 --- a/doc/paddle/tutorial/quick_start/high_level_api/high_level_api.rst +++ b/doc/paddle/tutorial/quick_start/high_level_api/high_level_api.rst @@ -38,6 +38,9 @@ paddle即可使用相关高层API,如:paddle.Model、视觉领域paddle.visi import paddle.vision as vision import paddle.text as text + # 启动动态图训练模式 + paddle.disable_static() + paddle.__version__ @@ -81,7 +84,7 @@ paddle即可使用相关高层API,如:paddle.Model、视觉领域paddle.visi .. parsed-literal:: 视觉相关数据集: ['DatasetFolder', 'ImageFolder', 'MNIST', 'Flowers', 'Cifar10', 'Cifar100', 'VOC2012'] - 自然语言相关数据集: ['Conll05st', 'Imdb', 'Imikolov', 'Movielens', 'MovieReviews', 'UCIHousing', 'WMT14', 'WMT16'] + 自然语言相关数据集: ['Conll05st', 'Imdb', 'Imikolov', 'Movielens', 'UCIHousing', 'WMT14', 'WMT16'] 这里我们是加载一个手写数字识别的数据集,用\ ``mode``\ 来标识是训练数据还是测试数据集。数据集接口会自动从远端下载数据集到本机缓存目录\ ``~/.cache/paddle/dataset``\ 。 @@ -145,8 +148,8 @@ paddle即可使用相关高层API,如:paddle.Model、视觉领域paddle.visi return len(self.data) # 测试定义的数据集 - train_dataset = MyDataset(mode='train') - val_dataset = MyDataset(mode='test') + train_dataset_2 = MyDataset(mode='train') + val_dataset_2 = MyDataset(mode='test') print('=============train dataset=============') for data, label in train_dataset: @@ -188,7 +191,7 @@ paddle即可使用相关高层API,如:paddle.Model、视觉领域paddle.visi transform = Compose([ColorJitter(), Resize(size=100)]) # 通过transform参数传递定义好的数据增项方法即可完成对自带数据集的应用 - train_dataset = vision.datasets.MNIST(mode='train', transform=transform) + train_dataset_3 = vision.datasets.MNIST(mode='train', transform=transform) 3.3.2 自定义数据集 ^^^^^^^^^^^^^^^^^^ @@ -284,7 +287,7 @@ paddle即可使用相关高层API,如:paddle.Model、视觉领域paddle.visi return y - mnist = Mnist() + mnist_2 = Mnist() 4.3 模型封装 ~~~~~~~~~~~~ @@ -297,8 +300,6 @@ paddle即可使用相关高层API,如:paddle.Model、视觉领域paddle.visi # 场景1:动态图模式 - # 启动动态图训练模式 - paddle.disable_static() # 使用GPU训练 paddle.set_device('gpu') # 模型封装 @@ -320,12 +321,76 @@ paddle即可使用相关高层API,如:paddle.Model、视觉领域paddle.visi model.summary((1, 28, 28)) + +.. parsed-literal:: + + -------------------------------------------------------------------------------- + Layer (type) Input Shape Output Shape Param # + ================================================================================ + Flatten-57509 [-1, 1, 28, 28] [-1, 784] 0 + Linear-7 [-1, 784] [-1, 512] 401,920 + ReLU-4 [-1, 512] [-1, 512] 0 + Dropout-4 [-1, 512] [-1, 512] 0 + Linear-8 [-1, 512] [-1, 10] 5,130 + ================================================================================ + Total params: 407,050 + Trainable params: 407,050 + Non-trainable params: 0 + -------------------------------------------------------------------------------- + Input size (MB): 0.00 + Forward/backward pass size (MB): 0.02 + Params size (MB): 1.55 + Estimated Total Size (MB): 1.57 + -------------------------------------------------------------------------------- + + + + + +.. parsed-literal:: + + {'total_params': 407050, 'trainable_params': 407050} + + + 另外,summary接口有两种使用方式,下面我们通过两个示例来做展示,除了\ ``Model.summary``\ 这种配套\ ``paddle.Model``\ 封装使用的接口外,还有一套配合没有经过\ ``paddle.Model``\ 封装的方式来使用。可以直接将实例化好的Layer子类放到\ ``paddle.summary``\ 接口中进行可视化呈现。 .. code:: ipython3 paddle.summary(mnist, (1, 28, 28)) + +.. parsed-literal:: + + -------------------------------------------------------------------------------- + Layer (type) Input Shape Output Shape Param # + ================================================================================ + Flatten-57508 [-1, 1, 28, 28] [-1, 784] 0 + Linear-5 [-1, 784] [-1, 512] 401,920 + ReLU-3 [-1, 512] [-1, 512] 0 + Dropout-3 [-1, 512] [-1, 512] 0 + Linear-6 [-1, 512] [-1, 10] 5,130 + ================================================================================ + Total params: 407,050 + Trainable params: 407,050 + Non-trainable params: 0 + -------------------------------------------------------------------------------- + Input size (MB): 0.00 + Forward/backward pass size (MB): 0.02 + Params size (MB): 1.55 + Estimated Total Size (MB): 1.57 + -------------------------------------------------------------------------------- + + + + + +.. parsed-literal:: + + {'total_params': 407050, 'trainable_params': 407050} + + + 这里面有一个注意的点,有的用户可能会疑惑为什么要传递\ ``(1, 28, 28)``\ 这个input_size参数,因为在动态图中,网络定义阶段是还没有得到输入数据的形状信息,我们想要做网络结构的呈现就无从下手,那么我们通过告知接口网络结构的输入数据形状,这样网络可以通过逐层的计算推导得到完整的网络结构信息进行呈现。如果是动态图运行模式,那么就不需要给summary接口传递输入数据形状这个值了,因为在Model封装的时候我们已经定义好了InputSpec,其中包含了输入数据的形状格式。 5. 模型训练 @@ -352,6 +417,31 @@ paddle即可使用相关高层API,如:paddle.Model、视觉领域paddle.visi batch_size=32, verbose=1) + +.. parsed-literal:: + + Epoch 1/10 + step 1875/1875 [==============================] - loss: 0.1600 - acc: 0.9022 - 10ms/step + Epoch 2/10 + step 1875/1875 [==============================] - loss: 0.0455 - acc: 0.9461 - 12ms/step + Epoch 3/10 + step 1875/1875 [==============================] - loss: 0.1429 - acc: 0.9544 - 19ms/step + Epoch 4/10 + step 1875/1875 [==============================] - loss: 0.0197 - acc: 0.9601 - 22ms/step + Epoch 5/10 + step 1875/1875 [==============================] - loss: 0.1762 - acc: 0.9644 - 25ms/step + Epoch 6/10 + step 1875/1875 [==============================] - loss: 0.1304 - acc: 0.9667 - 22ms/step + Epoch 7/10 + step 1875/1875 [==============================] - loss: 0.0133 - acc: 0.9682 - 22ms/step + Epoch 8/10 + step 1875/1875 [==============================] - loss: 0.0097 - acc: 0.9705 - 19ms/step + Epoch 9/10 + step 1875/1875 [==============================] - loss: 3.1264e-04 - acc: 0.9716 - 23ms/step + Epoch 10/10 + step 1875/1875 [==============================] - loss: 0.0767 - acc: 0.9729 - 13ms/step + + 5.1 单机单卡 ~~~~~~~~~~~~ @@ -359,8 +449,6 @@ paddle即可使用相关高层API,如:paddle.Model、视觉领域paddle.visi .. code:: ipython3 - # 启动动态图训练模式 - paddle.disable_static() # 使用GPU训练 paddle.set_device('gpu') @@ -379,15 +467,41 @@ paddle即可使用相关高层API,如:paddle.Model、视觉领域paddle.visi batch_size=32, verbose=1) + +.. parsed-literal:: + + Epoch 1/10 + step 1875/1875 [==============================] - loss: 0.0490 - acc: 0.9741 - 6ms/step + Epoch 2/10 + step 1875/1875 [==============================] - loss: 0.1384 - acc: 0.9760 - 7ms/step + Epoch 3/10 + step 1875/1875 [==============================] - loss: 0.0929 - acc: 0.9767 - 7ms/step + Epoch 4/10 + step 1875/1875 [==============================] - loss: 0.0190 - acc: 0.9772 - 6ms/step + Epoch 5/10 + step 1875/1875 [==============================] - loss: 0.0862 - acc: 0.9774 - 7ms/step + Epoch 6/10 + step 1875/1875 [==============================] - loss: 0.0748 - acc: 0.9785 - 8ms/step + Epoch 7/10 + step 1875/1875 [==============================] - loss: 0.0039 - acc: 0.9798 - 17ms/step + Epoch 8/10 + step 1875/1875 [==============================] - loss: 0.0037 - acc: 0.9808 - 11ms/step + Epoch 9/10 + step 1875/1875 [==============================] - loss: 0.0013 - acc: 0.9800 - 8ms/step + Epoch 10/10 + step 1875/1875 [==============================] - loss: 0.0376 - acc: 0.9810 - 8ms/step + + 5.2 单机多卡 ~~~~~~~~~~~~ 对于高层API来实现单机多卡非常简单,整个训练代码和单机单卡没有差异。直接使用\ ``paddle.distributed.launch``\ 启动单机单卡的程序即可。 -.. code:: ipython3 +.. code:: bash + + $ python -m paddle.distributed.launch train.py - # train.py里面包含的就是单机单卡代码 - python -m paddle.distributed.launch train.py +train.py里面包含的就是单机单卡代码 5.3 自定义Loss ~~~~~~~~~~~~~~ @@ -640,6 +754,14 @@ paddle即可使用相关高层API,如:paddle.Model、视觉领域paddle.visi result = model.evaluate(val_dataset, verbose=1) + +.. parsed-literal:: + + Eval begin... + step 10000/10000 [==============================] - loss: 0.0000e+00 - acc: 0.9801 - 2ms/step + Eval samples: 10000 + + 7. 模型预测 ----------- @@ -657,6 +779,14 @@ numpy_ndarray_n是对应原始数据经过模型计算后得到的预测数据 pred_result = model.predict(val_dataset) + +.. parsed-literal:: + + Predict begin... + step 10000/10000 [==============================] - 4ms/step + Predict samples: 10000 + + 7.1 使用多卡进行预测 ~~~~~~~~~~~~~~~~~~~~ @@ -678,10 +808,33 @@ infer.py里面就是包含model.predict的代码程序。 模型训练和验证达到我们的预期后,可以使用\ ``save``\ 接口来将我们的模型保存下来,用于后续模型的Fine-tuning(接口参数training=True)或推理部署(接口参数training=False)。 +需要注意的是,在动态图模式训练时保存推理模型的参数文件和模型文件,需要在forward成员函数上添加@paddle.jit.to_static装饰器,参考下面的例子: + +.. code:: python + + class Mnist(paddle.nn.Layer): + def __init__(self): + super(Mnist, self).__init__() + + self.flatten = paddle.nn.Flatten() + self.linear_1 = paddle.nn.Linear(784, 512) + self.linear_2 = paddle.nn.Linear(512, 10) + self.relu = paddle.nn.ReLU() + self.dropout = paddle.nn.Dropout(0.2) + + @paddle.jit.to_static + def forward(self, inputs): + y = self.flatten(inputs) + y = self.linear_1(y) + y = self.relu(y) + y = self.dropout(y) + y = self.linear_2(y) + + return y + .. code:: ipython3 - # 保存用于推理部署的模型(training=False) - model.save('~/model/mnist', training=False) + model.save('~/model/mnist') 8.2 预测部署 ~~~~~~~~~~~~ diff --git a/doc/paddle/tutorial/quick_start/save_model/save_model.ipynb b/doc/paddle/tutorial/quick_start/save_model/save_model.ipynb index 812d2631821db7dc9f3d73d408f607553a15534f..8c3d9e2c3820d8ed2ba3624705c2cee84a5e3f53 100644 --- a/doc/paddle/tutorial/quick_start/save_model/save_model.ipynb +++ b/doc/paddle/tutorial/quick_start/save_model/save_model.ipynb @@ -173,8 +173,8 @@ "#### paddle 基础框架-动态图-模型参数保存 \n", " * paddle.save\n", "#### paddle 基础框架-静态图-模型参数保存 \n", - " * paddle.io.save\n", - " * paddle.io.save_inference_model\n", + " * paddle.static.save\n", + " * paddle.static.save_inference_model\n", "\n", "下面将基于高阶API对模型保存与加载的方法进行讲解。" ] @@ -230,8 +230,8 @@ "#### paddle 基础框架-动态图-模型参数加载\n", " * paddle.load\n", "#### paddle 基础框架-静态图-模型参数加载\n", - " * paddle.io.load \n", - " * paddle.io.load_inference_model" + " * paddle.static.load \n", + " * paddle.static.load_inference_model" ] }, { diff --git a/doc/paddle/tutorial/quick_start/save_model/save_model.rst b/doc/paddle/tutorial/quick_start/save_model/save_model.rst index 91a6b2175580ec52de7a1d38d4cc51e4686b18c8..d5e1aae41b2d42fe365c5f5be3896d6ad82c2afc 100644 --- a/doc/paddle/tutorial/quick_start/save_model/save_model.rst +++ b/doc/paddle/tutorial/quick_start/save_model/save_model.rst @@ -127,8 +127,8 @@ import MNIST 引入即可。 目前Paddle框架有三种保存模型参数的体系,分别是: #### paddle 高阶API-模型参数保存 \* paddle.Model.fit \* paddle.Model.save #### paddle 基础框架-动态图-模型参数保存 \* paddle.save #### paddle -基础框架-静态图-模型参数保存 \* paddle.io.save \* -paddle.io.save_inference_model +基础框架-静态图-模型参数保存 \* paddle.static.save \* +paddle.static.save_inference_model 下面将基于高阶API对模型保存与加载的方法进行讲解。 @@ -168,8 +168,8 @@ paddle.io.save_inference_model 当恢复训练状态时,需要加载模型数据,此时我们可以使用加载函数从存储模型状态和优化器状态的文件中载入模型参数和优化器参数,如果不需要恢复优化器,则不必使用优化器状态文件。 #### 高阶API-模型参数加载 \* paddle.Model.load #### paddle 基础框架-动态图-模型参数加载 \* paddle.load #### paddle -基础框架-静态图-模型参数加载 \* paddle.io.load \* -paddle.io.load_inference_model +基础框架-静态图-模型参数加载 \* paddle.static.load \* +paddle.static.load_inference_model 下面将对高阶API的模型参数加载方法进行讲解 \* model.load(self, path, skip_mismatch=False, reset_optimizer=False)