Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add variant of new load and save ops for storing model params in a single file #7909

Merged
merged 15 commits into from
Jan 30, 2018

Conversation

sidgoyal78
Copy link
Contributor

This PR basically implements a different approach for issue #7722 , and is based on the suggestions in PR #7780.

Things added:

  • load_combine_op
  • save_combine_op
  • A unit test for saving and loading multiple LoDTensors
  • A unit test for saving and loading 1 LoDTensor (so as to verify that it performs the function of the original load_op and save_op as well).

TODO: To remove the original load_op and save_op and rename these.

"Cannot open file %s for load_combine op", filename);

auto out_var_names = Outputs("Out");
PADDLE_ENFORCE(out_var_names.size(), "Output variables cannot be found");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to PADDLE_ENFORCE_LT(out_var_names.size(), 0, "The number of output variables should be > 0.");

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. (I think you mean PADDLE_ENFORCE_GT :) )

auto *tensor = out_var->GetMutable<framework::LoDTensor>();

uint64_t data_length;
char *buffer = NULL;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is no need a buffer, we can directly use fin to read the file sequentially and deserialize the LoDTensor one by one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thanks for the suggestion.

current_serialized_data.assign(buffer, data_length);

// Create an input string stream
std::istringstream ist(current_serialized_data);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need another stream, we can directly use fin.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


auto *tensor = out_var->GetMutable<framework::LoDTensor>();

uint64_t data_length;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure is there still a need to save the data_length...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thanks for pointing this out. I have simplified the logic.

#include "gtest/gtest.h"
#include "paddle/framework/op_registry.h"

USE_NO_KERNEL_OP(save);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

save -> save_combine?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, thanks.

#include "paddle/framework/op_registry.h"

USE_NO_KERNEL_OP(save);
USE_NO_KERNEL_OP(load);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

load -> load_combine?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, thanks. Based on the naming issues, i fixed some other things as well. Thanks.

AddComment(R"DOC(
LoadCombine Operator.

LoadCombine operator combines together various tensor variable into a file.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be something like "load various tensor variables from a file"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, will change the comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@Xreki Xreki added the 预测 原名Inference,包含Capi预测问题等 label Jan 30, 2018
Copy link
Contributor

@Xreki Xreki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work~ It is almost LGTM except some minor aspects.
We can merge this PR first and fix the comments in next PR if it blocks other work.

public:
LoadCombineOpProtoMaker(OpProto *proto, OpAttrChecker *op_checker)
: OpProtoAndCheckerMaker(proto, op_checker) {
AddOutput("Out", "(LoDTensor) The tensor need to be load_combined")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(LoDTensor) The tensor need to be load_combined -> (vector) The tensors need to be loaded

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thanks.

.AsDuplicable();
AddAttr<std::string>("file_path",
"(string) "
"Variable will be load_combined from \"file_path\".")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable will be load_combined from "file_path". -> Variables will be loaded from "file_path".
or The file_path to load Variables.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

AddComment(R"DOC(
LoadCombine Operator.

LoadCombine operator loads tensor variables from a file.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More comments here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

PADDLE_ENFORCE(static_cast<bool>(fout), "Cannot open %s to write",
filename);

auto inames = Inputs("X");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inames -> in_names

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified, to make it consistent with variable name in load_combine: I modified it to inp_var_names

auto inames = Inputs("X");
PADDLE_ENFORCE_GT(
static_cast<int>(inames.size()), 0,
"The number of output variables should be greater than 0");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

output -> input

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

USE_NO_KERNEL_OP(save_combine);
USE_NO_KERNEL_OP(load_combine);

TEST(SaveLoadNewOp, CPU) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this unittest to save_load_combine_op_test.cc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

auto load_var = scope.Var(out_var_name);
auto target = load_var->GetMutable<paddle::framework::LoDTensor>();
return target;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a blank line here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

USE_NO_KERNEL_OP(save_combine);
USE_NO_KERNEL_OP(load_combine);

int* create_for_save_combine_op(int x, int y, const std::vector<int>& lod_info,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create_for_save_combine_op -> CreateSaveCombineOp
the same for following functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

return actual;
}

void check_values(int* expect, int* actual, paddle::framework::LoD expect_lod,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check_values -> CheckValues

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

@kexinzhao kexinzhao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@sidgoyal78 sidgoyal78 merged commit 2e907c3 into PaddlePaddle:develop Jan 30, 2018
@kexinzhao kexinzhao moved this from DOING to DONE in Inference Framework Feb 1, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
预测 原名Inference,包含Capi预测问题等
Projects
No open projects
Inference Framework
Basic Usage (DONE)
Development

Successfully merging this pull request may close these issues.

None yet

3 participants