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 cpp trainer lib and demo #10681

Merged
merged 33 commits into from
May 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
55bc1e1
add demo_network.py
jacquesqiao May 11, 2018
07ef3dd
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
jacquesqiao May 11, 2018
2becc31
python can run
jacquesqiao May 11, 2018
1c56311
add demo cmake list
jacquesqiao May 14, 2018
e6399d6
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
jacquesqiao May 14, 2018
a62093f
tmp
jacquesqiao May 14, 2018
9944bf8
tmp
jacquesqiao May 15, 2018
c1b5502
complete CMakeLists.txt
jacquesqiao May 15, 2018
865c951
optimize CMakeLists.txt
jacquesqiao May 15, 2018
8690e08
update boost dir
jacquesqiao May 15, 2018
7300015
can build and run
jacquesqiao May 15, 2018
531a223
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
jacquesqiao May 16, 2018
6310f05
delete optimizer, optimize cmake
jacquesqiao May 16, 2018
7c84808
optimize code, add document
jacquesqiao May 16, 2018
e31546a
revert code
jacquesqiao May 16, 2018
a8f0b43
code clean
jacquesqiao May 16, 2018
9291602
get loss after run program
jacquesqiao May 16, 2018
da5e462
optimize code
jacquesqiao May 16, 2018
1479a25
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
jacquesqiao May 16, 2018
acadffa
fix compile on server
jacquesqiao May 16, 2018
436e45b
Merge branch 'add-cpp-trainer-demo' of ssh://github.com/jacquesqiao/P…
jacquesqiao May 16, 2018
0652d3d
update cmake
jacquesqiao May 17, 2018
7088512
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
jacquesqiao May 17, 2018
6b6f7b5
Merge branch 'add-mkldnn-to-paddle-lib' of ssh://github.com/jacquesqi…
jacquesqiao May 17, 2018
2249237
update document
jacquesqiao May 17, 2018
3368d9a
update cmake
jacquesqiao May 17, 2018
454e9b3
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
jacquesqiao May 17, 2018
44dc25c
update lib install dir
jacquesqiao May 21, 2018
86212a8
Merge branch 'develop' of https://github.com/PaddlePaddle/Paddle into…
jacquesqiao May 21, 2018
d3882c3
optimize code and document
jacquesqiao May 21, 2018
dc03009
optimize code
jacquesqiao May 21, 2018
b59082d
optimize document
jacquesqiao May 21, 2018
1146843
follow comment, change 100 to 10
jacquesqiao May 21, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions paddle/fluid/train/demo/CMakeLists.txt
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})
66 changes: 66 additions & 0 deletions paddle/fluid/train/demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@

Copy link
Contributor

Choose a reason for hiding this comment

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

需要注明是使用CPU静态库的版本。GPU/动态库有点区别,但类似。

Copy link
Member Author

Choose a reason for hiding this comment

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

后面统一整理?目前业务方只需要用CPU的部分,可以先给他们用起来

### 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
Copy link
Contributor

Choose a reason for hiding this comment

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

@Superjomn 训练也使用的话,叫inference_lib_dist好么?改成fluid_lib_dist?

Copy link
Member Author

Choose a reason for hiding this comment

The 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
Copy link
Contributor

Choose a reason for hiding this comment

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

WARNING: Logging before InitGoogleLogging() is written to STDERR
W0521 20:55:43.756713 24692 init.cc:84] 'CUDA' is not supported, Please re-compile with WITH_GPU option
W0521 20:55:43.756901 24692 init.cc:100] 'CUDA' is not supported, Please re-compile with WITH_GPU option
step: 0 loss: 58.8651
step: 1 loss: 58.8651
step: 2 loss: 58.8651

我打出来是这样,每个阶段的loss都一样?

Copy link
Member Author

Choose a reason for hiding this comment

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

对,因为没有加入optimize op,有一个参数控制,https://github.com/PaddlePaddle/Paddle/pull/10681/files#diff-7e8d0736b2aff0b2bc699d05f454e0a3R19
这是业务的需求

Copy link
Member Author

Choose a reason for hiding this comment

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

加上之后可以正常收敛

....
```
47 changes: 47 additions & 0 deletions paddle/fluid/train/demo/demo_network.py
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)
103 changes: 103 additions & 0 deletions paddle/fluid/train/demo/demo_trainer.cc
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
Copy link
Contributor

Choose a reason for hiding this comment

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

ReadBinaryFile和load函数既然在paddle/train的namespace里面,是否应该放在paddle代码里,而不是demo代码里。

Copy link
Member Author

Choose a reason for hiding this comment

The 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;
}