From 202b0eaf0fc76e6c21036d16ac6834a75bc96993 Mon Sep 17 00:00:00 2001 From: Yiqun Liu Date: Mon, 26 Apr 2021 13:19:22 +0800 Subject: [PATCH] Unset ReserveSpace of batch_norm for inference program. (#32493) * Unset ReserveSpace for inference program. * Support training from an inference program. --- paddle/fluid/framework/op_desc.cc | 5 +++++ paddle/fluid/framework/op_desc.h | 1 + paddle/fluid/pybind/protobuf.cc | 1 + python/paddle/fluid/dygraph/io.py | 17 +++++++++++++++++ python/paddle/fluid/framework.py | 3 +++ 5 files changed, 27 insertions(+) diff --git a/paddle/fluid/framework/op_desc.cc b/paddle/fluid/framework/op_desc.cc index 7af5c54cee..519bf8c633 100644 --- a/paddle/fluid/framework/op_desc.cc +++ b/paddle/fluid/framework/op_desc.cc @@ -447,6 +447,11 @@ void OpDesc::SetOutput(const std::string ¶m_name, this->outputs_[param_name] = args; } +void OpDesc::RemoveOutput(const std::string &name) { + outputs_.erase(name); + need_update_ = true; +} + bool OpDesc::HasProtoAttr(const std::string &name) const { auto &op_info = OpInfoMap::Instance(); if (op_info.Has(desc_.type())) { diff --git a/paddle/fluid/framework/op_desc.h b/paddle/fluid/framework/op_desc.h index 95c33bca6c..1bc1a308e4 100644 --- a/paddle/fluid/framework/op_desc.h +++ b/paddle/fluid/framework/op_desc.h @@ -65,6 +65,7 @@ class OpDesc { void SetOutput(const std::string ¶m_name, const std::vector &args); + void RemoveOutput(const std::string &name); bool HasAttr(const std::string &name) const { return attrs_.find(name) != attrs_.end(); diff --git a/paddle/fluid/pybind/protobuf.cc b/paddle/fluid/pybind/protobuf.cc index 06b3f10fef..6fa49a8542 100644 --- a/paddle/fluid/pybind/protobuf.cc +++ b/paddle/fluid/pybind/protobuf.cc @@ -235,6 +235,7 @@ void BindOpDesc(pybind11::module *m) { const std::vector &vec_var_name) { self.SetOutput(name, vec_var_name); }) + .def("remove_output", &pd::OpDesc::RemoveOutput) .def("input_arg_names", &pd::OpDesc::InputArgumentNames) .def("output_arg_names", &pd::OpDesc::OutputArgumentNames) .def("_rename_input", &pd::OpDesc::RenameInput) diff --git a/python/paddle/fluid/dygraph/io.py b/python/paddle/fluid/dygraph/io.py index af4ba16ee8..ce40fde163 100644 --- a/python/paddle/fluid/dygraph/io.py +++ b/python/paddle/fluid/dygraph/io.py @@ -413,6 +413,23 @@ class _ProgramHolder(object): # Therefore, in order to reuse the method of backward.py, build the program here. program = _build_program_by_desc(program_desc_copy) + # 3. Add the outputs which is only used for training and not saved in + # inference program. + for block_idx in six.moves.range(program.num_blocks): + block = program.block(block_idx) + for op in block.ops: + if op.type == "batch_norm": + if "ReserveSpace" not in op.output_names or len( + op.output("ReserveSpace")) == 0: + reserve_space = block.create_var( + name=unique_name.generate_with_ignorable_key( + ".".join(["reserve_space", 'tmp'])), + dtype=block.var(op.input("X")[0]).dtype, + type=core.VarDesc.VarType.LOD_TENSOR, + persistable=False, + stop_gradient=True) + op.desc.set_output("ReserveSpace", [reserve_space.name]) + targets = [] for out in self._output_descs: targets.append(program.global_block().var(out.name())) diff --git a/python/paddle/fluid/framework.py b/python/paddle/fluid/framework.py index ccfec944a7..59e22f24f3 100644 --- a/python/paddle/fluid/framework.py +++ b/python/paddle/fluid/framework.py @@ -5021,6 +5021,9 @@ class Program(object): op = block.op(j) if op.has_attr('is_test'): op._set_attr('is_test', True) + if op.type() == "batch_norm": + # Remove the output ReserveSpace of batch_norm if exists. + op.remove_output("ReserveSpace") res.blocks = [ Block(res, i) for i in six.moves.range(res.desc.num_blocks()) ] -- GitLab