Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
FluidDoc
提交
836e1381
F
FluidDoc
项目概览
PaddlePaddle
/
FluidDoc
通知
5
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
23
列表
看板
标记
里程碑
合并请求
111
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
F
FluidDoc
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
23
Issue
23
列表
看板
标记
里程碑
合并请求
111
合并请求
111
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
836e1381
编写于
10月 26, 2019
作者:
S
sangoly
提交者:
GitHub
10月 26, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[Paddle-Lite] add Paddle-Lite doc test=document_preview (#1545)
上级
2660ae9b
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
40 addition
and
489 deletion
+40
-489
doc/fluid/advanced_usage/deploy/index_cn.rst
doc/fluid/advanced_usage/deploy/index_cn.rst
+1
-1
doc/fluid/advanced_usage/deploy/index_en.rst
doc/fluid/advanced_usage/deploy/index_en.rst
+1
-1
doc/fluid/advanced_usage/deploy/mobile/index_cn.rst
doc/fluid/advanced_usage/deploy/mobile/index_cn.rst
+2
-5
doc/fluid/advanced_usage/deploy/mobile/mobile_index.md
doc/fluid/advanced_usage/deploy/mobile/mobile_index.md
+36
-482
未找到文件。
doc/fluid/advanced_usage/deploy/index_cn.rst
浏览文件 @
836e1381
...
...
@@ -4,7 +4,7 @@
- `服务器端部署 <inference/index_cn.html>`_ :介绍了支持模型部署上线的Fluid C++ API
- `移动端部署 <mobile/index_cn.html>`_:介绍了 PaddlePaddle组织下的嵌入式平台深度学习框架Paddle-
Mobil
e
- `移动端部署 <mobile/index_cn.html>`_:介绍了 PaddlePaddle组织下的嵌入式平台深度学习框架Paddle-
Lit
e
.. toctree::
:hidden:
...
...
doc/fluid/advanced_usage/deploy/index_en.rst
浏览文件 @
836e1381
...
...
@@ -4,7 +4,7 @@ Deploy Inference Model
- `Server side Deployment <inference/index_en.html>`_ : This section illustrates Fluid C++ API to support deployment and release of trained models.
- `Paddle
Mobile <mobile/index_en.html>`_ : Embedded deep learning framework Paddle-Mobil
e organized by PaddlePaddle.
- `Paddle
Lite <mobile/index_en.html>`_ : Embedded deep learning framework Paddle-Lit
e organized by PaddlePaddle.
.. toctree::
:hidden:
...
...
doc/fluid/advanced_usage/deploy/mobile/index_cn.rst
浏览文件 @
836e1381
...
...
@@ -2,14 +2,11 @@
移动端部署
##########
本模块介绍了 PaddlePaddle 组织下的嵌入式平台深度学习框架——Paddle-
Mobil
e,包括:
本模块介绍了 PaddlePaddle 组织下的嵌入式平台深度学习框架——Paddle-
Lit
e,包括:
* `项目简介 <mobile_index.html>`_:简要介绍了 Paddle-Mobile 特点以及使用说明
* `开发者文档 <for_developer.html>`_:分别介绍如何开发扩展及编译 mobile 预测库
* `项目简介 <mobile_index.html>`_:简要介绍了 Paddle-Lite 特点以及使用说明
.. toctree::
:hidden:
mobile_index.md
for_developer.md
doc/fluid/advanced_usage/deploy/mobile/mobile_index.md
浏览文件 @
836e1381
# Paddle-
Mobil
e
# Paddle-
Lit
e
## 简介
Paddle Lite为Paddle-Mobile的升级版,定位支持包括手机移动端在内更多场景的轻量化高效预测,支持更广泛的硬件和平台,是一个高性能、轻量级的深度学习预测引擎。在保持和PaddlePaddle无缝对接外,也兼容支持其他训练框架产出的模型。
## 使用方法
完整使用文档位于
[
PaddleLite 文档
](
https://paddlepaddle.github.io/Paddle-Lite/
)
。
目前有两种 C++ 接口可以实现 mobile 预测:
## 特性
-
CxxConfig: 完整功能预测接口
-
MobileConfig: 专用于移动端的轻量级接口
### 轻量级
执行阶段和计算优化阶段实现良好解耦拆分,移动端可以直接部署执行阶段,无任何第三方依赖。
包含完整的80个 Op+85个 Kernel 的动态库,对于ARMV7只有800K,ARMV8下为1.3M,并可以裁剪到更低。
在应用部署时,载入模型即可直接预测,无需额外分析优化。
对应的 Java 接口也有两种:
### 高性能
极致的 ARM CPU 性能优化,针对不同微架构特点实现kernel的定制,最大发挥计算性能,在主流模型上展现出领先的速度优势。
支持INT8量化计算,结合
[
PaddleSlim 模型压缩工具
](
https://github.com/PaddlePaddle/models/tree/v1.5/PaddleSlim
)
中 INT8量化训练功能,可以提供高精度高性能的预测能力。
在Huawei NPU, FPGA上也具有有很好的性能表现。
-
loadCxxModel: 完整功能预测接口
-
loadMobileModel: 专用于移动端的轻量级接口
最新 Benchmark 位于
[
benchmark
](
https://paddlepaddle.github.io/Paddle-Lite/develop/benchmark/
)
。
前者输入原始预测模型,并执行相应的计算图优化后,实现高性能预测;后者输入计算图优化之后的模型,直接执行相关计算。
### 通用性
硬件方面,Paddle Lite 的架构设计为多硬件兼容支持做了良好设计。除了支持ARM CPU、Mali GPU、Adreno GPU,还特别支持了华为 NPU,以及 FPGA 等边缘设备广泛使用的硬件。即将支持支持包括寒武纪、比特大陆等AI芯片,未来会增加对更多硬件的支持。
### Java Basics
模型支持方面,Paddle Lite和PaddlePaddle训练框架的Op对齐,提供更广泛的模型支持能力。目前已严格验证18个模型85个OP的精度和性能,对视觉类模型做到了较为充分的支持,覆盖分类、检测和定位,包含了特色的OCR模型的支持。未来会持续增加更多模型的支持验证。
#### 编译
框架兼容方面:除了PaddlePaddle外,对其他训练框架也提供兼容支持。当前,支持Caffe 和 TensorFlow 训练出来的模型,通过X2Paddle (https://github.com/PaddlePaddle/X2Paddle) 转换工具实现。接下来将会对ONNX等格式模型提供兼容支持。
Java 接口需要在 cmake 选项中同时打开 DWITH_LITE, DLITE_WITH_JAVA, DLITE_WITH_ARM。 例如:
## 架构
```
shell
# ARM_TARGET_OS in "android" , "armlinux"
# ARM_TARGET_ARCH_ABI in "armv8", "armv7" ,"armv7hf"
# ARM_TARGET_LANG in "gcc" "clang"
mkdir
-p
build.lite.android.arm8.gcc
cd
build.lite.android.arm8.gcc
PaddleLite 的架构设计着重考虑了对多硬件和平台的支持,并且强化了多个硬件在一个模型中混合执行的能力,多个层面的性能优化处理,以及对端侧应用的轻量化设计。
cmake ..
\
-DWITH_GPU
=
OFF
\
-DWITH_MKL
=
OFF
\
-DWITH_LITE
=
ON
\
-DLITE_WITH_JAVA
=
ON
\
-DLITE_WITH_CUDA
=
OFF
\
-DLITE_WITH_X86
=
OFF
\
-DLITE_WITH_ARM
=
ON
\
-DLITE_WITH_LIGHT_WEIGHT_FRAMEWORK
=
ON
\
-DWITH_TESTING
=
ON
\
-DARM_TARGET_OS
=
android
-DARM_TARGET_ARCH_ABI
=
armv8
-DARM_TARGET_LANG
=
gcc
![](
https://github.com/Superjomn/_tmp_images/raw/master/images/paddle-lite-architecture.png
)
make
-j4
```
其中,Analysis Phase 包括了 MIR(Machine IR) 相关模块,能够对原有的模型的计算图针对具体的硬件列表进行算子融合、计算裁剪 在内的多种优化。Execution Phase 只涉及到Kernel 的执行,且可以单独部署,以支持极致的轻量级部署。
make 成功后,Linux下会生成动态库文件 paddle/fluid/lite/api/android/jni/libpaddle_lite_jni.so( Mac 下为
libpaddle_lite_jni.jnilib, Windows 下为libpaddle_lite_jni.dll )该动态库即 Java JNI ( Java Native Interface ) 所需要的
C++ 接口动态链接库,下面例子中我们将使用 Linux 下 libpaddle_lite_jni.so 为例。同时,也会在同一个文件夹下生成
PaddlePredictor.jar
#### Android 程序构建
## Paddle-Mobile升级为Paddle Lite的说明
原Paddle-Mobile作为一个致力于嵌入式平台的PaddlePaddle预测引擎,已支持多种硬件平台,包括ARM CPU、 Mali GPU、Adreno GPU,以及支持苹果设备的GPU Metal实现、ZU5、ZU9等FPGA开发板、树莓派等arm-linux开发板。在百度内已经过广泛业务场景应用验证。对应设计文档可参考:
[
mobile/README
](
https://github.com/PaddlePaddle/Paddle-Lite/blob/develop/mobile/README.md
)
在我们的库中,Java 代码库被放在 paddle/fluid/lite/api/android/jni/src 中,具体有两个classes:
Paddle-Mobile 整体升级重构并更名为Paddle Lite后,原paddle-mobile 的底层能力大部分已集成到
[
新架构
](
https://github.com/PaddlePaddle/Paddle-Lite/tree/develop/lite
)
下。作为过渡,暂时保留原Paddle-mobile代码。 主体代码位于
`mobile/`
目录中,后续一段时间会继续维护,并完成全部迁移。新功能会统一到
[
新架构
](
https://github.com/PaddlePaddle/Paddle-Lite/tree/develop/lite
)
下开发。
com.baidu.paddle.lite.PaddlePredictor
com.baidu.paddle.lite.Place
metal, web的模块相对独立,会继续在
`./metal`
和
`./web`
目录下开发和维护。对苹果设备的GPU Metal实现的需求及web前端预测需求,可以直接进入这两个目录。
你可以将其打包成 .jar 或者直接使用 Java 源代码接口。如果要使用 .jar,我们上节编译中生成的 .jar 也可以直接使用。
## 致谢
Paddle Lite 借鉴了以下开源项目:
请将 JNI 动态链接库放在 Android Studio 代码 jniLibs 文件夹对应的体系结构文件夹下。例如要在 arm8 架构的手机,就 在 src/main/jniLibs/arm8 文件夹下放置 libpaddle_lite_jni.so,文件路径如果不存在请创建。
-
[
ARM compute library
](
https://github.com/ARM-software/ComputeLibrary
)
-
[
Anakin
](
https://github.com/PaddlePaddle/Anakin
)
,Anakin对应底层的一些优化实现已被集成到Paddle Lite。Anakin作为PaddlePaddle组织下的一个高性能预测项目,极具前瞻性,对Paddle Lite有重要贡献。Anakin已和本项目实现整合。之后,Anakin不再升级。
接下来,我们将具体介绍PaddlePredictor.java 和 Place.java
## 交流与反馈
*
欢迎您通过Github Issues来提交问题、报告与建议
*
微信公众号:飞桨PaddlePaddle
*
QQ群: 696965088
#### 代码接口 Place
Paddle 预测中,为了便于管理不同的硬件及kernel 的其他实现细节,定义如下四个信息:
-
Target: 具体的硬件空间,比如
`ARM`
表示 ARM CPU,
`OPEN_CL`
表示 OpenCL
-
DataLayout: Tensor 中的数据排布,目前有
`NCHW`
-
Precison: kernel 的计算精度,或者 Tensor 的存储类型,目前有
`FLOAT`
,
`INT8`
等
-
`Device`
: 硬件的 device id,可以是 0 开始的整数
前三个为Java enum,最后一个为整型。相关定义如下
```
java
public
enum
TargetType
{
UNKNOWN
(
0
),
HOST
(
1
),
X86
(
2
),
CUDA
(
3
),
ARM
(
4
),
OPEN_CL
(
5
),
ANY
(
6
);
}
public
enum
PrecisionType
{
UNKNOWN
(
0
),
FLOAT
(
1
),
INT8
(
2
),
INT32
(
3
),
ANY
(
4
);
}
public
enum
DataLayoutType
{
UNKNOWN
(
0
),
NCHW
(
1
),
ANY
(
2
);
}
```
而 Place 就是这四个信息的整合,其数据结构为
```
java
public
class
Place
{
public
TargetType
target
;
public
PrecisionType
precision
;
public
DataLayoutType
layout
;
public
int
device
;
};
```
Place 用于标记Kernel 的主要计算模式,比如
`place.precision=INT8`
的 kernel 表示为 Int8量化的 kernel。Place 暴露给用户,用户帮助指定模型硬件及量化等模式。
#### 代码接口 PaddlePredictor
PaddlePredictor 提供的 methods 都是 native static methods。整体上运行的思路为
载入模型 -> 设置输入 -> 运行模型 -> 获取输出/存储运行后优化的模型 -> 清理掉载入的模型
我们将介绍各个步骤的主要功能,具体接口的参数和返回值请见Javadoc:
1.
载入模型:
```java
// 载入没有优化过的原始模型,用户可以设置期望的 Place 和可选的 Place
public static native boolean loadCxxModel(String modelPath, Place preferredPlace, Place[] validPlaces);
// 载入没有优化过的原始模型,用户可以设置期望的 Place 和可选的 Place
public static native boolean loadMobileModel(String modelPath);
```
2.
设置输入
```java
// 设置第 offest (从0开始)输入的维度和float数据
public static native boolean setInput(int offset, int[] dims, float[] buf);
// 设置第 offest (从0开始)输入的维度和byte数据 (在c++端为int8)
public static native boolean setInput(int offset, int[] dims, byte[] buf);
```
3.
运行模型
```
java
// 运行模型
public
static
native
boolean
run
();
```
4.
获取输出
```
java
// 获取第 offset (从0开始)的 float 输出
public
static
native
float
[]
getFloatOutput
(
int
offset
);
// 获取第 offset (从0开始)的 byte 输出
public
static
native
byte
[]
getByteOutput
(
int
offset
);
// 指定名字获取 Var 的 float 输出
public
static
native
float
[]
fetchFloat
(
String
name
);
// 指定名字获取 Var 的 byte 输出
public
static
native
byte
[]
fetchByte
(
String
name
);
```
5.
存储运行后优化的模型
```java
public static native boolean saveOptimizedModel(String modelPath);
```
6.
清理掉载入的模型
```
java
public
static
native
boolean
clear
();
```
使用示例如下:
```
java
String
modelPath
=
"lite_naive_model"
;
// 用户定义的模型路径
// 用户自定义的输入,例子里是 100 * 100 的 float
float
[]
inputBuffer
=
new
float
[
10000
];
for
(
int
i
=
0
;
i
<
10000
;
++
i
)
{
inputBuffer
[
i
]
=
i
;
}
int
[]
dims
=
{
100
,
100
};
// Cxx Model 设定 Place
Place
preferredPlace
=
new
Place
(
Place
.
TargetType
.
X86
,
Place
.
PrecisionType
.
FLOAT
);
Place
[]
validPlaces
=
new
Place
[
2
];
validPlaces
[
0
]
=
preferredPlace
;
validPlaces
[
1
]
=
new
Place
(
Place
.
TargetType
.
ARM
,
Place
.
PrecisionType
.
FLOAT
);
// 载入模型
PaddlePredictor
.
loadCxxModel
(
modelPath
,
preferredPlace
,
validPlaces
);
// 设置输入
PaddlePredictor
.
setInput
(
0
,
dims
,
inputBuffer
);
// 运行Predictor
PaddlePredictor
.
run
();
// 获取输出
float
[]
cxxOutput
=
PaddlePredictor
.
getFloatOutput
(
0
);
// 保持优化后的模型在新路径
String
optimizedModelPath
=
modelPath
+
".opt"
;
PaddlePredictor
.
saveOptimizedModel
(
optimizedModelPath
);
// 清除已载入的模型
PaddlePredictor
.
clear
();
// Mobile Model 载入优化后的模型
PaddlePredictor
.
loadMobileModel
(
optimizedModelPath
);
// 设置输入
PaddlePredictor
.
setInput
(
0
,
dims
,
inputBuffer
);
// 运行
PaddlePredictor
.
run
();
// 获取输出
float
[]
mobileOutput
=
PaddlePredictor
.
getFloatOutput
(
0
);
```
### C++ Basics
在使用前,有几个基本概念:
#### Place
Place 在 C++ 中概念与 Java 相同,为了便于管理不同的硬件及kernel 的其他实现细节,定义如下四个信息:
-
Target: 具体的硬件空间,比如
`kARM`
表示 ARM CPU,
`kOpenCL`
表示 OpenCL
-
DataLayout: Tensor 中的数据排布,目前有
`kNCHW`
-
Precison: kernel 的计算精度,或者 Tensor 的存储类型,目前有
`kFloat`
,
`kInt8`
等
-
`Device`
: 硬件的 device id,可以是0开始的整数
前三个为结构体,最后一个为整型。相关定义如下
```
c++
enum
class
TargetType
:
int
{
kUnk
=
0
,
kHost
,
kX86
,
kCUDA
,
kARM
,
kOpenCL
,
kAny
,
// any target
NUM
,
// number of fields.
};
enum
class
PrecisionType
:
int
{
kUnk
=
0
,
kFloat
,
kInt8
,
kInt32
,
kAny
,
// any precision
NUM
,
// number of fields.
};
enum
class
DataLayoutType
:
int
{
kUnk
=
0
,
kNCHW
,
kAny
,
// any data layout
NUM
,
// number of fields.
};
```
而 Place 就是这四个信息的整合,其数据结构为
```
c++
struct
Place
{
TargetType
target
{
TARGET
(
kUnk
)};
PrecisionType
precision
{
PRECISION
(
kUnk
)};
DataLayoutType
layout
{
DATALAYOUT
(
kUnk
)};
int16_t
device
{
0
};
// device ID
};
```
Place 用于标记Kernel 的主要计算模式,比如
`place.precision=kInt8`
的 kernel 表示为 Int8量化的 kernel。Place 暴露给用户层,用户帮助指定模型执行的硬件及量化等执行模式。
#### Config
预测接口使用的第一步是执行
`CreatePaddlePredictor(config)`
接口创建一个 predictor,具体的 config 目前有多个选择,对应着也会模板特化出不同的 predictor以适应不同的场景。
模板接口如下
```
c++
template
<
typename
ConfigT
>
std
::
shared_ptr
<
PaddlePredictor
>
CreatePaddlePredictor
(
const
ConfigT
&
);
```
接下来会详细介绍两种 Config:
`CxxConfig`
和
`MobileConfig`
.
### CxxConfig 及对应 Predictor
接口如下:
-
`set_model_dir(const std::string& x)`
设置模型路径(目前只支持
`__model__`
+
`params`
两个文件的模型格式)
-
`set_preferred_place(const Place& x)`
设置期望的执行 Place
-
`set_valid_places(const std::vector<Place>& x)`
设置可选的 Place
`valid_places`
用于设置模型可执行的 Place 范围,底层会根据place 信息挑选出具体的硬件执行 kernel,而
`preferred_place`
用于指定
`valid_places`
中最优先执行的 Place,从而使对应 place 的 kernel 更优先被选择.
比如,要执行 ARM FP32 量化预测,可以设置
```
c++
CxxConfig
config
;
config
.
set_model_dir
(
"xxx"
);
// model_dir 为必须选项
// 设置有效的Place信息
config
.
set_valid_places
({
Place
{
TARGET
(
kARM
),
PRECISION
(
kFloat
)}});
// 当每个Op有多个kernel可选择的时候,优先选择preferred_place可运行的kernel。
config
.
set_preferred_place
(
Place
{
TARGET
(
kARM
),
PRECISION
(
kInt8
)});
```
创建完 config 之后可以继续获得 predictor 来执行预测
```
c++
auto
predictor
=
CreatePaddlePredictor
(
config
);
```
获取模型的输入和输出 tensor 以填充或获取数据。
这里的 Tensor 都是 handle,用户最好复用。
```
c++
auto
x_tensor
=
predictor
->
GetInput
(
0
/*index*/
);
// 这里的 0 表示输入序列的 offset,具体的顺序由训练中 save_inference_model 存储决定
// 注意,这里的 x_tensor 是一个 unique_ptr,也就是一个对应的 handle,用户可以在每个 batch 都复用
// 这个 handle.
auto
out_tensor
=
predictor
->
GetOutput
(
0
/*index*/
);
// 这里 out_tensor 是只读的
```
这里的 Tensor 提供了用户需要的详细的信息,其定义如下,用户可以自由使用其他接口
```
c++
struct
Tensor
{
void
Resize
(
const
shape_t
&
shape
);
/// Readonly data.
template
<
typename
T
>
const
T
*
data
()
const
;
template
<
typename
T
>
T
*
mutable_data
()
const
;
/// Shape of the tensor.
shape_t
shape
()
const
;
};
```
接着上面例子,
`x_tensor`
是第
`0`
个输入的 Tensor,是可写的。 可以类似如下方式准备输入
```
c++
// 指定 batch_size=10, 其余维度为 200, 30
// 注意,这里的维度需要参考实际模型做修改
x_tensor
->
Resize
({
10
,
200
,
30
});
// Resize 更新 shape 后,调用 mutable_data 来实际分配内存
auto
x_data
=
x_tensor
->
mutable_data
<
float
>
();
// 可以随意修改 x_data 的输入,比如 memcpy(x_data, some_data, some_size);
```
模型可能有多个输入,如上类似
`x_tensor`
,调用
`GetInput(i)`
获得其余 tensor 并修改。
输入准备完毕,就可以执行预测:
```
c++
// 执行模型的预测,模型会基于前面设定的 input tensor,执行模型计算,并填充 output tensor
predictor
->
Run
();
```
执行完毕,可以获取 output tensor 的数据
```
c++
// 获得 output tensor 的 shape
auto
out_shape
=
out_tensor
->
shape
();
// 获得具体的 data,是一块连续的 memory
const
auto
*
out_data
=
out_tensor
->
data
<
float
>
();
```
### MobileConfig
`MobileConfig`
基本用法类似于
`CxxConfig`
,具体区别是
-
CxxConfig 会执行完整的预测,包括图分析等较重的逻辑
-
输入为原始的预测模型,无需做离线处理
-
可以将图分析优化完的模型存储下来(借助 SaveOptimizedModel 接口),用于
`MobileConfig`
-
MobileConfig 考虑到手机应用的空间及初始化时长的限制,阉割掉图分析的能力,只执行预测本身
-
更轻量级
-
输入模型必须为图分析优化完的模型 (借助 CxxConfig 作离线处理)
由于 MobileConfig 的输入模型必须为优化完的模型,相应的 Kernel 的 Place 由输入模型决定,因此没有 CxxConfig 中 指定Place的接口,目前只有指定模型路径的接口:
-
`void set_model_dir(const std::string& x)`
使用 MobileConfig 的其余步骤 与CxxConfig 完全一致。
### GenCode 功能介绍
Mobile 支持将模型和预测库结合,转化为 C++代码,进而融合成一个链接库,在设备上执行
`paddle_code_generator`
及相应参数便可转化。
### INT8量化预测
Paddle-Mobile支持对
[
PaddleSlim
](
https://github.com/PaddlePaddle/models/tree/develop/PaddleSlim
)
中量化训练得到的模型的预测。
其中使用方法如下:
```
c++
CxxConfig
config
;
config
.
set_model_dir
(
"xxx"
);
// model_dir 为必须选项
// 由于 ARM Int8 模式只包括 Conv,MUL 等少数量化 kernel,因此需要一并选择上 Float 的 kernel
config
.
set_valid_places
({
Place
{
TARGET
(
kARM
),
PRECISION
(
kInt8
)},
// Int8 计算 kernel
Place
{
TARGET
(
kARM
),
PRECISION
(
kFloat
)}
// Float 也需要选择以补充
});
// 上面同时选择了 kInt8 和 kFloat 两类模式的 kernel,下面设置 kInt8 的 kernel 为优先选择
config
.
set_preferred_place
(
Place
{
TARGET
(
kARM
),
PRECISION
(
kInt8
)});
```
目前该功能已在Mobilenetv1上进行了验证,并且还在持续开发中。
## 源码编译
### ARM CPU
当前ARM 上可以支持arm v8和v7的交叉编译。环境可以直接使用
`paddle/fluid/lite/tools/Dockerfile.mobile`
生成docker镜像。
-
主要的cmake选项
-
`ARM_MATH_LIB_DIR`
代表arm相关数学库的路径,可以从官网指定路径下载。
-
`ARM_TARGET_OS`
代表目标操作系统, 目前支持 "android" "armlinux", 默认是Android
-
`ARM_TARGET_ARCH_ABI`
代表ARCH,支持输入"armv8"和"armv7",针对OS不一样选择不一样。
-
`-DARM_TARGET_OS="android"`
时
-
"armv8", 等效于 "arm64-v8a"。 default值为这个。
-
"armv7", 等效于 "armeabi-v7a"。
-
`-DARM_TARGET_OS="armlinux"`
时
-
"armv8", 等效于 "arm64"。 default值为这个。当前仅支持这个输入。
-
`ARM_TARGET_LANG`
代表目标编译的语言, 默认为gcc,支持 gcc和clang两种。
-
参考示例
```
shell
# ARM_TARGET_OS in "android" , "armlinux"
# ARM_TARGET_ARCH_ABI in "armv8", "armv7" ,"armv7hf"
# ARM_TARGET_LANG in "gcc" "clang"
cmake ..
\
-DWITH_GPU
=
OFF
\
-DWITH_MKL
=
OFF
\
-DWITH_LITE
=
ON
\
-DLITE_WITH_CUDA
=
OFF
\
-DLITE_WITH_X86
=
OFF
\
-DLITE_WITH_ARM
=
ON
\
-DLITE_WITH_LIGHT_WEIGHT_FRAMEWORK
=
ON
\
-DARM_MATH_LIB_DIR
=
"<to_arm_math_libs_path>"
\
-DWITH_TESTING
=
ON
\
-DARM_TARGET_OS
=
"android"
-DARM_TARGET_ARCH_ABI
=
"armv8"
-DARM_TARGET_LANG
=
"gcc"
make
-j4
```
### OpenCL
Paddle-Mobile支持在Android系统上运行基于OpenCL的程序,目前提供armv8和armv7的交叉编译。
#### 编译
-
编译环境: 使用
`paddle/fluid/lite/tools/Dockerfile.mobile`
生成docker镜像。
-
cmake编译选型介绍
*
`ARM_TARGET_OS`
代表目标操作系统, 目前仅支持 "android", 亦为默认值。
*
`ARM_TARGET_ARCH_ABI`
代表ARCH,支持输入"armv8"和"armv7"。其中,"armv8",
等效于 "arm64-v8a",亦为默认值;"armv7", 等效于 "armeabi-v7a"。
*
`ARM_TARGET_LANG`
代表目标编译的语言, 默认为gcc,支持 gcc和clang两种。
-
参考示例
```shell
# ARM_TARGET_OS in "android"
# ARM_TARGET_ARCH_ABI in "armv8", "armv7" ,"armv7hf"
# ARM_TARGET_LANG in "gcc" "clang"
# 假设我们处于源码根目录下
mkdir build_opencl && cd build_opencl
cmake .. \
-DLITE_WITH_OPENCL=ON \
-DWITH_GPU=OFF \
-DWITH_MKL=OFF \
-DWITH_LITE=ON \
-DLITE_WITH_CUDA=OFF \
-DLITE_WITH_X86=OFF \
-DLITE_WITH_ARM=ON \
-DLITE_WITH_LIGHT_WEIGHT_FRAMEWORK=ON \
-DWITH_TESTING=ON \
-DARM_TARGET_OS="android" -DARM_TARGET_ARCH_ABI="armv8" -DARM_TARGET_LANG="gcc"
# 完整编译
make -j4
# 或者我们也可以make某一target文件
make test_mobilenetv1_lite -j4
make test_cl_runtime -j4
make test_elementwise_add_opencl -j4
make test_pool_opencl -j4
```
#### 运行
-
运行文件准备
使用如下命令将运行OpenCL程序时需要加载的文件push到手机端(假设我们处于源码根目录下):
```
# 我们将文件统一push到/data/local/tmp/opencl目录下
adb shell mkdir -p /data/local/tmp/opencl
# 将OpenCL的kernels文件push到/data/local/tmp/opencl目录下
adb push paddle/fluid/lite/opencl/cl_kernel /data/local/tmp/opencl
# 将mobilenet_v1的模型文件push到/data/local/tmp/opencl目录下
adb push build_opencl/third_party/install/mobilenet_v1 /data/local/tmp/opencl
# 将OpenCL测试程序(如test_mobilenetv1_lite) push到/data/local/tmp/opencl目录下
adb push paddle/fluid/lite/api/test_mobilenetv1_lite /data/local/tmp/opencl
```
-
运行OpenCL程序
使用如下命令运行OpenCL程序。其中,
`--cl_path`
指定了OpenCL的kernels文件即cl
\_
kernel所在目录,
`--modle_dir`
指定了模型文件所在目录。
```
shell
adb shell
cd
/data/local/tmp/opencl
&&
./test_mobilenetv1_lite
--cl_path
=
.
--model_dir
=
mobilenet_v1
```
<p
align=
"center"
><img
width=
"200"
height=
"200"
src=
"https://user-images.githubusercontent.com/45189361/64117959-1969de80-cdc9-11e9-84f7-e1c2849a004c.jpeg"
/>
     
<img
width=
"200"
height=
"200"
margin=
"500"
src=
"https://user-images.githubusercontent.com/45189361/64117844-cb54db00-cdc8-11e9-8c08-24bbe594608e.jpeg"
/></p>
<p
align=
"center"
>
   
微信公众号
                
官方技术交流QQ群
</p>
*
论坛: 欢迎大家在
[
PaddlePaddle论坛
](
https://ai.baidu.com/forum/topic/list/168
)
分享在使用PaddlePaddle中遇到的问题和经验, 营造良好的论坛氛围
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录