下面我来详细讲解“详解Windows下源码编译PaddlePaddle”的完整攻略以及包含的两条示例说明。
一、前置条件
在开始操作之前,请先确保你已经安装好以下工具:
- Visual Studio 2017及以上版本(建议使用VS2019)
- CMake 3.18及以上版本
- Git
- Python 3.7及以上版本
- CUDA Toolkit和cuDNN库(可选,主要用于GPU加速)
另外,还需要了解以下知识:
- 源码编译的基本概念
- Windows下编译过程的基本流程
二、源码编译PaddlePaddle的步骤
- 下载源码
git clone https://github.com/PaddlePaddle/Paddle.git
- 配置CMake参数
在源码根目录下新建一个build目录,并进入该目录。执行以下cmake命令,指定编译参数:
cmake .. -G "Visual Studio 16 2019" -A x64 ^
-DWITH_API=OFF ^
-DWITH_FLUID_ONLY=ON ^
-DWITH_PYTHON=ON ^
-DWITH_PYTHON3=ON ^
-DWITH_TESTING=OFF ^
-DWITH_MKL=OFF ^
-DWITH_GPU=OFF
以上是一些常用的配置参数,具体可以根据实际情况选择。
- 编译PaddlePaddle
使用Visual Studio打开生成的Paddle.sln文件,编译整个PaddlePaddle项目。编译完成后,生成的库文件会保存在build目录下的python/paddle/fluid/core/
、python/paddle/fluid/operators/
和python/paddle/fluid/framework/
等路径下。
- 安装PaddlePaddle
在源码根目录下执行以下命令安装PaddlePaddle:
python -m pip install -e .
至此,PaddlePaddle源码已经成功编译并安装。
三、示例说明
示例一:调用PaddlePaddle的Python API
使用编译好的PaddlePaddle库,你可以轻松地在Python代码中调用PaddlePaddle的API。
import paddle.fluid as fluid
x = fluid.layers.data(name="x", shape=[784], dtype="float32")
y_predict = fluid.layers.fc(input=x, size=10, act='softmax')
place = fluid.CUDAPlace(0)
exe = fluid.Executor(place)
exe.run(fluid.default_startup_program())
x_np = np.random.rand(1, 784).astype('float32')
output_np = exe.run(feed={'x': x_np}, fetch_list=[y_predict])[0]
示例二:自定义OP并编译
假设我们要实现一个自定义的OP,在PaddlePaddle中实现两个数相加的操作。我们可以仿照源码中的sum_op
自定义一个add_op
:
#pragma once
#include "paddle/fluid/framework/op_registry.h"
#include "paddle/fluid/framework/operator.h"
#include "paddle/fluid/framework/tensor.h"
#include "paddle/fluid/platform/device_context.h"
namespace paddle {
namespace operators {
class AddOp : public framework::OperatorBase {
public:
AddOp(const std::string& type, const framework::VariableNameMap& inputs,
const framework::VariableNameMap& outputs,
const framework::AttributeMap& attrs,
std::shared_ptr<framework::Scope> scope)
: framework::OperatorBase(type, inputs, outputs, attrs, scope) {}
void Run(const framework::Scope& scope,
const platform::Place& device_context) const override {
auto& input_a_var = scope.FindVar(Input("X"));
auto& input_b_var = scope.FindVar(Input("Y"));
auto& output_var = *scope.FindVar(Output("Out"));
auto& input_a_tensor = input_a_var->Get<framework::Tensor>();
auto& input_b_tensor = input_b_var->Get<framework::Tensor>();
auto* output_tensor = output_var.GetMutable<framework::Tensor>();
PADDLE_ENFORCE_EQ(input_a_tensor.place(), input_b_tensor.place(),
"Input tensors must be on the same place!");
output_tensor->mutable_data<float>(input_a_tensor.place());
auto* output_data = output_tensor->mutable_data<float>();
const auto* input_a_data = input_a_tensor.data<float>();
const auto* input_b_data = input_b_tensor.data<float>();
size_t num = input_a_tensor.numel();
for (size_t i = 0; i < num; i++) {
output_data[i] = input_a_data[i] + input_b_data[i];
}
}
};
class AddOpMaker : public framework::OpProtoAndCheckerMaker {
public:
void Make() override {
AddInput("X", "The first input of add op.");
AddInput("Y", "The second input of add op.");
AddOutput("Out", "The output of add op.");
AddComment(R"DOC(
Add operation.
Out = X + Y
)DOC");
}
};
} // namespace operators
} // namespace paddle
这里我们编写的add_op
实现了输入数据X
和Y
的加法操作,并将结果输出到Out
中。
接下来,我们需要将add_op
编译成DLL文件,供PaddlePaddle调用。请确保您的CMake已经正确配置以编译自定义OP,然后执行以下命令:
cd paddle/fluid/operators
mkdir build && cd build
cmake .. -G "Visual Studio 16 2019" -A x64 -DPADDLE_ROOT=../../../../.. -DCMAKE_CONFIGURATION_TYPES="Debug;Release" -DWITH_STATIC_LIB=OFF
cmake --build . --config Release
执行完成后,你就可以在build_fluid_operators_vcxproj/Release
目录下找到编译好的paddle_add_op.dll
文件。
最后,在使用add_op
的Python代码中引入编译好的DLL库,并进行调用:
import paddle.fluid as fluid
import numpy as np
# 加载自定义OP库
fluid.load_op_library('path/to/paddle_add_op.dll')
# 定义网络
x_1 = fluid.layers.data(name="x1", shape=[1], dtype="float32") # 输入1
x_2 = fluid.layers.data(name="x2", shape=[1], dtype="float32") # 输入2
y_predict = fluid.layers.py_func(
func=lambda x, y: np.add(x, y), # 操作函数
x=[x_1, x_2],
out=fluid.framework.Variable(), # 输出
dygraph_mode=False, # 关闭动态图模式
grad_func=None, # 不需要提供梯度函数
name='add_op') # 自定义OP名称
place = fluid.CPUPlace()
exe = fluid.Executor(place)
exe.run(fluid.default_startup_program())
x1_np = np.array([1.0]).astype('float32')
x2_np = np.array([2.0]).astype('float32')
output_np = exe.run(feed={'x1': x1_np, 'x2': x2_np}, fetch_list=[y_predict])[0]
这样就可以轻松地实现我们自定义的add_op
操作啦!
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Windows下源码编译PaddlePaddle - Python技术站