-
Notifications
You must be signed in to change notification settings - Fork 5.7k
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 cpp trainer lib and demo #10681
Add cpp trainer lib and demo #10681
Changes from all commits
55bc1e1
07ef3dd
2becc31
1c56311
e6399d6
a62093f
9944bf8
c1b5502
865c951
8690e08
7300015
531a223
6310f05
7c84808
e31546a
a8f0b43
9291602
da5e462
1479a25
acadffa
436e45b
0652d3d
7088512
6b6f7b5
2249237
3368d9a
454e9b3
44dc25c
86212a8
d3882c3
dc03009
b59082d
1146843
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
cmake_minimum_required(VERSION 3.0) | ||
|
||
project(cpp_train_demo CXX C) | ||
|
||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") | ||
|
||
if(NOT DEFINED PADDLE_LIB) | ||
message(FATAL_ERROR "please set PADDLE_LIB with -DPADDLE_LIB=/paddle/lib/dir") | ||
endif() | ||
|
||
option(WITH_MKLDNN "Compile PaddlePaddle with MKLDNN" OFF) | ||
option(WITH_MKL "Compile PaddlePaddle with MKL support, default use openblas." OFF) | ||
|
||
include_directories("${PADDLE_LIB}") | ||
include_directories("${PADDLE_LIB}/third_party/install/protobuf/include") | ||
include_directories("${PADDLE_LIB}/third_party/install/glog/include") | ||
include_directories("${PADDLE_LIB}/third_party/install/gflags/include") | ||
include_directories("${PADDLE_LIB}/third_party/install/snappy/include") | ||
include_directories("${PADDLE_LIB}/third_party/install/snappystream/include") | ||
include_directories("${PADDLE_LIB}/third_party/install/zlib/include") | ||
|
||
include_directories("${PADDLE_LIB}/third_party/boost") | ||
include_directories("${PADDLE_LIB}/third_party/eigen3") | ||
|
||
link_directories("${PADDLE_LIB}/third_party/install/snappy/lib") | ||
link_directories("${PADDLE_LIB}/third_party/install/snappystream/lib") | ||
link_directories("${PADDLE_LIB}/third_party/install/protobuf/lib") | ||
link_directories("${PADDLE_LIB}/third_party/install/glog/lib") | ||
link_directories("${PADDLE_LIB}/third_party/install/gflags/lib") | ||
link_directories("${PADDLE_LIB}/third_party/install/zlib/lib") | ||
|
||
add_executable(demo_trainer demo_trainer.cc) | ||
|
||
if(WITH_MKLDNN) | ||
include_directories("${PADDLE_LIB}/third_party/install/mkldnn/include") | ||
set(MKLDNN_LIB ${PADDLE_LIB}/third_party/install/mkldnn/lib/libmkldnn.so.0) | ||
endif() | ||
|
||
if(WITH_MKL) | ||
include_directories("${PADDLE_LIB}/third_party/install/mklml/include") | ||
set(MATH_LIB ${PADDLE_LIB}/third_party/install/mklml/lib/libmklml_intel.so) | ||
else() | ||
if(APPLE) | ||
set(MATH_LIB cblas) | ||
else(APPLE) | ||
set(MATH_LIB ${PADDLE_LIB}/third_party/install/openblas/lib/libopenblas.a) | ||
endif(APPLE) | ||
endif() | ||
|
||
if(APPLE) | ||
set(MACOS_LD_FLAGS "-undefined dynamic_lookup -Wl,-all_load -framework CoreFoundation -framework Security") | ||
else(APPLE) | ||
set(ARCHIVE_START "-Wl,--whole-archive") | ||
set(ARCHIVE_END "-Wl,--no-whole-archive") | ||
set(EXTERNAL_LIB "-lrt -ldl -lpthread") | ||
endif(APPLE) | ||
|
||
target_link_libraries(demo_trainer | ||
${MACOS_LD_FLAGS} | ||
${ARCHIVE_START} | ||
${PADDLE_LIB}/paddle/fluid/inference/libpaddle_fluid.a | ||
${ARCHIVE_END} | ||
${MATH_LIB} | ||
${MKLDNN_LIB} | ||
glog gflags protobuf snappystream snappy z | ||
${EXTERNAL_LIB}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
|
||
### step 1. build paddle lib | ||
|
||
``` | ||
|
||
# WITH_MKL=ON|OFF | ||
# WITH_MKLDNN=ON|OFF | ||
|
||
PADDLE_LIB=/paddle/lib/dir | ||
cmake .. -DCMAKE_INSTALL_PREFIX=$PADDLE_LIB \ | ||
-DCMAKE_BUILD_TYPE=Release \ | ||
-DWITH_FLUID_ONLY=ON \ | ||
-DWITH_GPU=OFF \ | ||
-DWITH_STYLE_CHECK=OFF \ | ||
-DWITH_MKL=OFF \ | ||
-DWITH_MKLDNN=OFF | ||
make -j8 | ||
make -j8 inference_lib_dist | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Superjomn 训练也使用的话,叫inference_lib_dist好么?改成fluid_lib_dist? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 打算后面统一整理一下,这个demo可以尽快merge |
||
``` | ||
|
||
### step 2. generate program desc | ||
``` | ||
# please install paddle before run this scripe | ||
pip install --upgrade paddlepaddle-*.whl | ||
python demo_network.py | ||
``` | ||
|
||
This will generate two program desc files: | ||
- startup_program: used to init all parameters | ||
- main_program: main logic of the network | ||
|
||
### step 3. build demo_trainer and run it. | ||
|
||
|
||
``` | ||
# Make a build dir at the same dir of this README.md document. | ||
# The demo dir can be put anywhere. | ||
mkdir build | ||
cd build | ||
|
||
# WITH_MKL=ON|OFF | ||
# WITH_MKLDNN=ON|OFF | ||
PADDLE_LIB=/paddle/lib/dir | ||
|
||
# PADDLE_LIB is the same with CMAKE_INSTALL_PREFIX when building the lib | ||
cmake .. -DPADDLE_LIB=$PADDLE_LIB \ | ||
-DWITH_MKLDNN=OFF \ | ||
-DWITH_MKL=OFF | ||
make | ||
|
||
# copy startup_program and main_program to this dir | ||
cp ../startup_program . | ||
cp ../main_program . | ||
|
||
# run demo cpp trainer | ||
./demo_trainer | ||
|
||
``` | ||
|
||
The output will be: | ||
``` | ||
step: 0 loss: 1069.02 | ||
step: 1 loss: 1069.02 | ||
step: 2 loss: 1069.02 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
我打出来是这样,每个阶段的loss都一样? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 对,因为没有加入optimize op,有一个参数控制,https://github.com/PaddlePaddle/Paddle/pull/10681/files#diff-7e8d0736b2aff0b2bc699d05f454e0a3R19 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 加上之后可以正常收敛 |
||
.... | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
import paddle.fluid as fluid | ||
import paddle.fluid.framework as framework | ||
|
||
|
||
def train_network(with_optimize): | ||
x = fluid.layers.data(name='x', shape=[13], dtype='float32') | ||
y_predict = fluid.layers.fc(input=x, size=1, act=None) | ||
|
||
y = fluid.layers.data(name='y', shape=[1], dtype='float32') | ||
cost = fluid.layers.square_error_cost(input=y_predict, label=y) | ||
avg_cost = fluid.layers.mean(cost) | ||
|
||
if with_optimize: | ||
sgd_optimizer = fluid.optimizer.SGD(learning_rate=0.00001) | ||
sgd_optimizer.minimize(avg_cost) | ||
else: | ||
fluid.backward.append_backward(avg_cost) | ||
|
||
|
||
def save_program_desc(network_func): | ||
startup_program = framework.Program() | ||
train_program = framework.Program() | ||
|
||
with framework.program_guard(train_program, startup_program): | ||
network_func(with_optimize=False) | ||
|
||
with open("startup_program", "w") as f: | ||
f.write(startup_program.desc.serialize_to_string()) | ||
with open("main_program", "w") as f: | ||
f.write(train_program.desc.serialize_to_string()) | ||
|
||
|
||
save_program_desc(train_network) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#include <fstream> | ||
|
||
#include "paddle/fluid/framework/executor.h" | ||
#include "paddle/fluid/framework/init.h" | ||
#include "paddle/fluid/framework/op_registry.h" | ||
#include "paddle/fluid/framework/program_desc.h" | ||
#include "paddle/fluid/framework/tensor_util.h" | ||
#include "paddle/fluid/platform/device_context.h" | ||
#include "paddle/fluid/platform/place.h" | ||
|
||
namespace paddle { | ||
namespace train { | ||
|
||
void ReadBinaryFile(const std::string& filename, std::string* contents) { | ||
std::ifstream fin(filename, std::ios::in | std::ios::binary); | ||
PADDLE_ENFORCE(static_cast<bool>(fin), "Cannot open file %s", filename); | ||
fin.seekg(0, std::ios::end); | ||
contents->clear(); | ||
contents->resize(fin.tellg()); | ||
fin.seekg(0, std::ios::beg); | ||
fin.read(&(contents->at(0)), contents->size()); | ||
fin.close(); | ||
} | ||
|
||
std::unique_ptr<paddle::framework::ProgramDesc> Load( | ||
paddle::framework::Executor* executor, const std::string& model_filename) { | ||
VLOG(3) << "loading model from " << model_filename; | ||
std::string program_desc_str; | ||
ReadBinaryFile(model_filename, &program_desc_str); | ||
|
||
std::unique_ptr<paddle::framework::ProgramDesc> main_program( | ||
new paddle::framework::ProgramDesc(program_desc_str)); | ||
return main_program; | ||
} | ||
|
||
} // namespace train | ||
} // namespace paddle | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ReadBinaryFile和load函数既然在paddle/train的namespace里面,是否应该放在paddle代码里,而不是demo代码里。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 打算后面统一整理一下 |
||
|
||
int main() { | ||
paddle::framework::InitDevices(false); | ||
|
||
const auto cpu_place = paddle::platform::CPUPlace(); | ||
|
||
paddle::framework::Executor executor(cpu_place); | ||
paddle::framework::Scope scope; | ||
auto startup_program = paddle::train::Load(&executor, "startup_program"); | ||
auto train_program = paddle::train::Load(&executor, "main_program"); | ||
|
||
std::string loss_name = ""; | ||
for (auto op_desc : train_program->Block(0).AllOps()) { | ||
if (op_desc->Type() == "mean") { | ||
loss_name = op_desc->Output("Out")[0]; | ||
break; | ||
} | ||
} | ||
|
||
PADDLE_ENFORCE_NE(loss_name, "", "loss not found"); | ||
|
||
// init all parameters | ||
executor.Run(*startup_program.get(), &scope, 0); | ||
|
||
// prepare data | ||
auto x_var = scope.Var("x"); | ||
auto x_tensor = x_var->GetMutable<paddle::framework::LoDTensor>(); | ||
x_tensor->Resize({2, 13}); | ||
|
||
auto x_data = x_tensor->mutable_data<float>(cpu_place); | ||
for (int i = 0; i < 2 * 13; ++i) { | ||
x_data[i] = static_cast<float>(i); | ||
} | ||
|
||
auto y_var = scope.Var("y"); | ||
auto y_tensor = y_var->GetMutable<paddle::framework::LoDTensor>(); | ||
y_tensor->Resize({2, 1}); | ||
auto y_data = y_tensor->mutable_data<float>(cpu_place); | ||
for (int i = 0; i < 2 * 1; ++i) { | ||
y_data[i] = static_cast<float>(i); | ||
} | ||
|
||
auto loss_var = scope.Var(loss_name); | ||
|
||
for (int i = 0; i < 10; ++i) { | ||
executor.Run(*train_program.get(), &scope, 0, false, true); | ||
std::cout << "step: " << i << " loss: " | ||
<< loss_var->Get<paddle::framework::LoDTensor>().data<float>()[0] | ||
<< std::endl; | ||
} | ||
return 0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
需要注明是使用CPU静态库的版本。GPU/动态库有点区别,但类似。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
后面统一整理?目前业务方只需要用CPU的部分,可以先给他们用起来