Skip to content

Commit f0e516a

Browse files
authored
Merge pull request #3028 from alibaba/feature/sync
MNN:Sync: Sync Internal 2.9.5
2 parents a8b7997 + c01ec71 commit f0e516a

File tree

356 files changed

+17965
-51048
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

356 files changed

+17965
-51048
lines changed

3rd_party/OpenCLHeaders/CL/cl2.hpp

-4
Original file line numberDiff line numberDiff line change
@@ -403,10 +403,6 @@
403403
# pragma message("cl2.hpp: USE_CL_DEVICE_FISSION is deprecated. Define CL_HPP_USE_CL_DEVICE_FISSION instead")
404404
# define CL_HPP_USE_CL_DEVICE_FISSION
405405
#endif
406-
#if !defined(CL_HPP_ENABLE_EXCEPTIONS) && defined(__CL_ENABLE_EXCEPTIONS)
407-
# pragma message("cl2.hpp: __CL_ENABLE_EXCEPTIONS is deprecated. Define CL_HPP_ENABLE_EXCEPTIONS instead")
408-
# define CL_HPP_ENABLE_EXCEPTIONS
409-
#endif
410406
#if !defined(CL_HPP_NO_STD_VECTOR) && defined(__NO_STD_VECTOR)
411407
# pragma message("cl2.hpp: __NO_STD_VECTOR is deprecated. Define CL_HPP_NO_STD_VECTOR instead")
412408
# define CL_HPP_NO_STD_VECTOR

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ option(MNN_INTERNAL "Build with MNN internal features, such as model authenticat
6363
option(MNN_JNI "Build MNN Jni for java to use" OFF)
6464
option(MNN_SUPPORT_BF16 "Enable MNN's bf16 op" OFF)
6565
option(MNN_LOW_MEMORY "Build MNN support low memory for weight quant model." OFF)
66+
option(MNN_CPU_WEIGHT_DEQUANT_GEMM "Build MNN CPU weight dequant related gemm kernels." OFF)
6667

6768
IF (OHOS)
6869
include($ENV{NODE_PATH}/@ali/tcpkg/tcpkg.cmake)

codegen/OpFuse.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ bool codegen(std::vector<Schedule::OpCacheInfo>& infos, std::vector<std::vector<
275275
auto inputs = tensors.first;
276276
auto outputs = tensors.second;
277277
// build Plugin Op
278-
SharedPtr<Command> cmdPlugin;
278+
std::shared_ptr<Command> cmdPlugin;
279279
{
280280
auto sourceCode = fuseModule.codegen();
281281
if(mapKernelSources.find(sourceCode) == mapKernelSources.end()) {

docs/compile/cmake.md

+1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ MNN使用CMake构建项目,CMake中的宏定义列表如下:
8080
| MNN_OPENCV_BENCH | 构建MNN的OpenCV功能是否开启性能benchmark,默认为`OFF` |
8181
| MNN_VULKAN_IMAGE | 构建MNN的Vulkan后端时采用Image内存模式,以便支持FP16和部分移动端上GPU的加速,默认为`ON` |
8282
| MNN_LOW_MEMORY | 是否支持低内存模式,支持低内存模式使用权值量化模型并设置`low_memory`则会使用计算时反量化,默认为`OFF` |
83+
| MNN_CPU_WEIGHT_DEQUANT_GEMM | 是否编译CPU权重反量化的矩阵乘Kernel, 如果打开该编译宏并且在CPU推理时设置MNN::BackendConfig::MemoryMode=Memory_Normal,就会使用权重反量化算子进行权重量化模型的推理,默认为`OFF` |
8384
| MNN_SUPPORT_RENDER | 是否支持图形渲染相关算子实现,默认为 `OFF` |
8485
| MNN_SUPPORT_TRANSFORMER_FUSE | 是否支持Fuse Transformer相关OP实现,默认为 `OFF` |
8586
| MNN_BUILD_LLM | 是否构建基于MNN的llm库和demo,默认为`OFF` |

docs/contribute/backend.md

+53-37
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# 自定义后端
2-
Backend是MNN对计算设备的抽象。MNN当前已经支持CPU、Vulkan、OpenCL、Metal等Backend,**只在计算设备暂未支持时新增Backend**,新增Op,请参阅[新增Op文档](customize_op)
2+
Runtime-Backend是MNN对计算设备的抽象。MNN当前已经支持CPU、Vulkan、OpenCL、Metal、CUDA等Backend,**只在计算设备暂未支持时新增Backend**,新增Op,请参阅[新增Op文档](op)
3+
4+
35

46
## 声明
57
所有新增Backend都需继承`Backend`类,并实现所有纯虚函数。
@@ -10,8 +12,10 @@ class XPUBackend final : public Backend {
1012
virtual Execution* onCreate(const std::vector<Tensor*>& inputs, const std::vector<Tensor*>& outputs, const MNN::Op* op) override;
1113
virtual void onExecuteBegin() const override;
1214
virtual void onExecuteEnd() const override;
13-
virtual bool onAcquireBuffer(const Tensor* tensor, StorageType storageType) override;
14-
virtual bool onReleaseBuffer(const Tensor* tensor, StorageType storageType) override;
15+
virtual void onResizeBegin() override;
16+
virtual ErrorCode onResizeEnd() override;
17+
18+
virtual MemObj* onAcquire(const Tensor* tensor, StorageType storageType) override;
1519
virtual bool onClearBuffer() override;
1620
virtual void onCopyBuffer(const Tensor* srcTensor, const Tensor* dstTensor) const override;
1721
}
@@ -91,7 +95,7 @@ static XPUCreatorRegister<XPUPoolingCreator> __reg(OpType_Pooling);
9195
```
9296
9397
## 内存管理
94-
Backend通过`onAcquireBuffer`为tensor分配内存,通过`onReleaseBuffer`为tensor释放内存。内存有三种存储模式:`STATIC`内存不复用,一般用于op常量存储;`DYNAMIC`内存可复用,一般用于变量存储;`DYNAMIC_SEPERATE`内存在pipeline间可复用,一般用于pipeline常量存储。`_onAcquireBuffer_`_和_`_onReleaseBuffer_`_中可以不实际分配/释放内存,只记录内存用量变更,在_`_onAllocateBuffer_`_调用时,再根据用量计算出优化方案,一次性完成分配/释放。_
98+
Backend通过`onAcquire`创建`MemObj`内存对象,定义其析构函数以便为tensor释放内存。内存有三种存储模式:`STATIC`内存不复用,一般用于op常量存储;`DYNAMIC`内存可复用,一般用于变量存储;`DYNAMIC_SEPERATE`内存在pipeline间可复用,一般用于pipeline常量存储。
9599
96100
```cpp
97101
/** backend buffer storage type */
@@ -118,31 +122,13 @@ enum StorageType {
118122
*/
119123
DYNAMIC_SEPERATE
120124
};
121-
/**
122-
* @brief allocate buffer of tensor for given storage type.
123-
* @param tensor buffer provider.
124-
* @param storageType buffer storage type.
125-
* @return success or not.
126-
*/
127-
virtual bool onAcquireBuffer(const Tensor* tensor, StorageType storageType) = 0;
128-
/**
129-
* @brief release buffer of tensor for given storage type.
130-
* @param tensor buffer provider.
131-
* @param storageType buffer storage type.
132-
* @return success or not.
133-
*/
134-
virtual bool onReleaseBuffer(const Tensor* tensor, StorageType storageType) = 0;
135-
```
136-
137-
在所有内存都分配完成后,backend会收到`onAllocateBuffer`回调:
138-
```cpp
139-
/**
140-
* @brief callback after all buffers needed by backend ops were allocated.
141-
* @return success or not. (result not used currently)
142-
*/
143-
virtual bool onAllocateBuffer() {
144-
return true;
145-
}
125+
/**
126+
* @brief allocate buffer of tensor for given storage type.
127+
* @param tensor buffer provider.
128+
* @param storageType buffer storage type.
129+
* @return MemObj for release, if failed, return nullptr.
130+
*/
131+
virtual MemObj* onAcquire(const Tensor* tensor, StorageType storageType) = 0;
146132
```
147133

148134
Backend在调用`onClearBuffer`时,需要释放所有`DYNAMIC``DYNAMIC_SEPERATE`存储模式的内存:
@@ -189,17 +175,47 @@ virtual void onExecuteEnd() const = 0;
189175
190176
```
191177

192-
## 注册Backend
193-
最后,定义Backend Creator,注册方法中调用`MNNInsertExtraBackendCreator`就可以完成Backend的注册,这里的注册方法需要在BackendRegister.cpp中声明并调用:
178+
## Runtime(运行时)
179+
对于使用同一种后端,且存在先后顺序,不会同时运行的模型,MNN提供机制使其共享部分计算资源,比如线程池,内存池等等。
180+
这部分计算资源使用Runtime存储。而Backend则由Runtime创建
181+
182+
### 实现Runtime
183+
Runtime主要实现如下接口:
184+
185+
```
186+
virtual Backend* onCreate(const BackendConfig* config = nullptr, Backend* origin = nullptr) const = 0;
187+
188+
/**
189+
@brief reset runtime
190+
*/
191+
virtual void onReset(int numberThread, const BackendConfig* config, bool full) {
192+
// Do nothing
193+
}
194+
195+
/**
196+
@brief clear unuseful resource
197+
@param level clear level: 0 - 100, bigger mean clear more, smaller mean cache more
198+
*/
199+
virtual void onGabageCollect(int level) = 0;
200+
201+
```
202+
203+
- onCreate :创建 Backend
204+
- onReset :重设默认配置
205+
- onGabageCollect :清理资源以节省内存
206+
207+
208+
### 注册Runtime
209+
注册方法中调用`MNNInsertExtraRuntimeCreator`就可以完成Runtime的注册,这里的注册方法需要在Backend.cpp中声明并调用:
194210
```cpp
195-
class XPUBackendCreator : public BackendCreator {
196-
virtual Backend *onCreate(const Backend::Info &info) const {
197-
return new MetalBackend;
211+
class XPURuntimeCreator : public RuntimeCreator {
212+
virtual Runtime* onCreate(const Backend::Info &info) const {
213+
return new XPURuntime;
198214
}
199215
};
200-
void registerCPUBackendCreator() {
201-
MNNInsertExtraBackendCreator(MNN_FORWARD_CPU, new CPUBackendCreator);
216+
void registerXPURuntimeCreator() {
217+
MNNInsertExtraBackendCreator(MNN_FORWARD_XPU, new XPURuntimeCreator);
202218
};
203219
```
204220
205-
使用cmake编译时,完成代码修改后,也需要相应修改CMakeLists.txt。
221+
使用cmake编译时,完成代码修改后,也需要相应修改CMakeLists.txt。

docs/contribute/op.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
# 自定义算子
22
## 概述
3-
在添加自定义算子前,请参阅[算子列表](../en/ops),避免不必要的重复。
3+
在添加自定义算子前,请查看算子列表,避免不必要的重复。
4+
5+
```bash
6+
./MNNConvert -f CAFFE --OP
7+
./MNNConvert -f TF --OP
8+
./MNNConvert -f ONNX --OP
9+
./MNNConvert -f TORCH --OP
10+
```
11+
412
### MNN 算子转换与实现结构
513
MNN 的算子转换与实现如下图,
614
- 模型转换包括以下步骤,二选一:

docs/faq.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -250,15 +250,15 @@ OpenCL / Vulkan 采用静态变量自注册的方式往 MNN 主库注册后端.
250250
251251
252252
## 性能相关
253-
### 使用 GPU 时,调用 copyToHostTensor / copyFromHostTensor 非常慢
253+
### 使用 GPU 时,调用 copyToHostTensor / readMap 非常慢
254254
GPU 后端调用 copy 的时间包含两个部分
255255
256256
- 异构数据拷贝
257257
- 等待数据相关的GPU计算完成
258258
259259
对 GPU 后端而言,在数据被要求对用户可见(比如复制 output tensor 数据出来)之前,是允许异步执行的。
260260
在数据被用户要求可见之时,会等待相应的异步操作完成。
261-
因此有可能 复制 output tensor 的过程包括了等待 GPU 算子异步执行完成,导致缓慢
261+
因此有可能 复制 output tensor 的过程包括了等待 GPU 算子异步执行完成,导致看上去缓慢
262262
### GPU 为什么比 CPU 跑得慢?
263263
有如下原因:
264264

docs/index.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272

7373
.. toctree::
7474
:maxdepth: 1
75-
:caption: 测试工具
75+
:caption: 工具集
7676
:name: tools
7777

7878
tools/convert

docs/inference/module.md

+77-9
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,25 @@
55
- 模型推理与`Session`的区别是不需要用户显式resize,支持控制流,所以当模型中有`if``while`时必须使用`Module`推理
66
### 相关数据结构
77
- `Module` Module接口的核心类,表示一个模型的虚类;实际加载模型时会创建其子类
8-
- `Executor` 包含若干个`RuntimeManager`,提供内存管理接口,每个`Executor`必须在单线程环境下运行。默认提供全局 `Executor`,需要并发执行时,可自行创建。
9-
- `ExecutorScope` 用于在子线程中绑定`Executor`,多线程并发必需
10-
- `VARP` 作为`Module`的输入输出,也是[Expr API](expr.md)中的基础数据结构
8+
- `Executor` 提供内存管理和后端资源管理能力,每个`Executor`必须在单线程环境下运行。同一个`Executor`可以用于多个顺序执行的`Module`
9+
- `ExecutorScope` 用于在子线程中绑定`Executor`,多线程并发必需。默认在创建`Module`时使用全局 `Executor`,如果有多个Module在不同线程并发执行时,需要各自创建`Executor`,并用`ExecutorScope`绑定。
10+
- `VARP` `Module`的输入输出,也是[Expr API](expr.md)中的基础数据结构
1111

1212
## 工作流程
13-
配置Executor(可选) -> 创建 RuntimeManager(可选) -> 创建Module -> 创建输入VARP -> 使用Module::forwad推理 -> 使用输出VARP -> 销毁Module
14-
### (可选)配置Executor
15-
`Executor`给用户提供接口来配置推理后端、线程数等属性,以及做性能统计、算子执行的回调函数、内存回收等功能。 提供一个全局的Exector对象,用户不用创建或持有对象即可直接使用
13+
创建和配置Executor -> 创建 RuntimeManager(可选) -> 创建Module -> 创建输入VARP -> 使用Module::forwad推理 -> 使用输出VARP -> 销毁Module -> 销毁Executor
14+
### 创建和配置Executor
15+
`Executor`给用户提供接口来配置推理后端、线程数等属性,以及做性能统计、算子执行的回调函数、内存回收等功能。 推荐针对自身模块创建单独的Executor ,若使用全局的Exector对象,对于多个模块在不同线程运行时可能会发生冲突
1616
```cpp
17-
// 配置默认全局Exector
18-
MNN::BackendConfig backend_config; // default backend config
17+
// 创建Exector
18+
MNN::BackendConfig backendConfig; // default backend config
19+
std::shared_ptr<MNN::Express::Executor> executor = MNN::Express::Executor::newExecutor(MNN_FORWARD_CPU, backendConfig, 1);
20+
1921
// 设置使用4线程+CPU
20-
MNN::Express::Executor::getGlobalExecutor()->setGlobalExecutorConfig(MNN_FORWARD_CPU, backend_config, 4);
22+
executor->setGlobalExecutorConfig(MNN_FORWARD_CPU, backend_config, 4);
23+
24+
// 绑定Executor,在创建/销毁/使用Module或进行表达式计算之前都需要绑定
25+
MNN::Express::ExecutorScope _s(executor);
26+
2127
```
2228
2329
### (可选)创建 RuntimeManager
@@ -39,6 +45,68 @@ std::shared_ptr<MNN::Express::Executor::RuntimeManager> rtmgr(MNN::Express::Exec
3945
rtmgr->setCache(".cachefile");
4046
```
4147
48+
RuntimeManager 可以设置 hint , mode , cache, externalpath ,以支持扩展功能。
49+
50+
```
51+
void setCache(std::string cacheName);
52+
void updateCache();
53+
void setMode(Interpreter::SessionMode mode);
54+
void setHint(Interpreter::HintMode mode, int value);
55+
void setExternalPath(std::string path, int type);
56+
bool getInfo(Interpreter::SessionInfoCode code, void* ptr);
57+
```
58+
59+
#### cache 设置
60+
对于GPU后端(Metal/OpenCL等),可以设置缓存文件路径,存储AutoTuning结果和Program编译结果,以加速第二次之后的Module load 过程。
61+
62+
```
63+
std::shared_ptr<Executor::RuntimeManager> rtmgr(Executor::RuntimeManager::createRuntimeManager(config));
64+
rtmgr->setCache(cacheFileName);
65+
66+
std::shared_ptr<Module> module(Module::load(inputNames, outputNames, modelName.c_str(), rtmgr, mdConfig));
67+
/*... Make Inputs*/
68+
auto outputs = module->onForward(inputs);
69+
70+
// Update cache file
71+
rtmgr->updateCache();
72+
```
73+
74+
#### mode 设置
75+
可以通过设置mode开启/关闭一些功能,示例:
76+
77+
```
78+
// 创建出来的 Module 支持插入回调函数
79+
rtmgr->setMode(Interpreter::Session_Debug);
80+
```
81+
82+
并非所有枚举都适用 Module 的创建,有效值如下:
83+
84+
- Interpreter::SessionMode::Session_Debug : 支持逐算子调试
85+
- Interpreter::SessionMode::Session_Release : 关闭逐算子调试功能,可以轻微提升性能【默认选项】
86+
- Interpreter::SessionMode::Session_Backend_Fix : 固定使用用户设置的后端【默认选项】
87+
- Interpreter::SessionMode::Session_Backend_Auto : MNN根据用户倾向,预估load Module耗时,如果耗时较短则使用用户设置的后端,否则使用CPU
88+
89+
90+
#### hint 设置
91+
通过 hint 设置,可以在后端支持的情况下设置相应属性,有效值如下:
92+
93+
- Interpreter::HintMode::WINOGRAD_MEMORY_LEVEL :使用 Winograd 算法优化卷积时,内存占用倾向,默认为 3 ,若希望降低内存占用可设为 0
94+
- Interpreter::HintMode::GEOMETRY_COMPUTE_MASK :几何计算相关优化开关,1为区域合并,2为复合区域合并,4为使用loop算子,8为支持几何计算重计算,需要多个功能开启时把对应值叠加。默认为功能全开。
95+
- Interpreter::HintMode::DYNAMIC_QUANT_OPTIONS :动态量化选项,1为 Per Batch,2为Per Tensor 。默认为2。
96+
- Interpreter::HintMode::CPU_LITTLECORE_DECREASE_RATE :对于 Android 设备存在大中小核的情况,大核算力到中核算力的衰减比例。默认为50(中核算力为大核的50%)
97+
98+
99+
#### ExternalPath
100+
在设备可能出现内存不足时,可以通过 setExternalPath 指定路径,让MNN把部分内存用mmap分配。这样操作系统可在内存不足时会将其转换为读写文件,避免内存不足程序闪退。示例:
101+
102+
```
103+
runtime_manager_->setExternalPath("tmp", MNN::Interpreter::EXTERNAL_WEIGHT_DIR);
104+
runtime_manager_->setExternalPath("tmp", MNN::Interpreter::EXTERNAL_FEATUREMAP_DIR);
105+
```
106+
107+
- MNN::Interpreter::EXTERNAL_WEIGHT_DIR : 权重重排后的内存转换为文件存储
108+
- MNN::Interpreter::EXTERNAL_FEATUREMAP_DIR : 中间内存转换为文件存储
109+
42110
### 创建Module
43111
`Module`可以通过指定模型,输入输出的名称,配置文件创建
44112
```cpp

docs/start/overall.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
### 训练
77
在训练框架上,根据训练数据训练出模型的阶段。虽然当前MNN也提供了[训练模型的能力](../train/expr.md),但主要用于端侧训练或模型调优。在数据量较大时,依然建议使用成熟的训练框架,如TensorFlow、PyTorch等。除了自行训练外,也可以直接利用开源的预训练模型。
88
### 转换
9-
将其他训练框架模型转换为MNN模型的阶段。MNN当前支持Tensorflow(Lite)、Caffe、ONNX和TorchScript的模型转换。模型转换工具可以参考[编译文档](../compile/tools.html#id2)[使用说明](../tools/convert.md)。支持转换的算子,可以参考[算子列表文档](../tools/convert.html#id7);在遇到不支持的算子时,可以尝试[自定义算子](../contribute/op.md),或在Github上给我们[提交issue](https://github.com/alibaba/MNN/issues/74)。此外,[模型打印工具](../tools/convert.html#id8)可以用于输出模型结构,辅助调试。除模型转换外,MNN也提供了[模型量化工具](../tools/quant.md),可以对浮点模型进行量化压缩。
9+
将其他训练框架模型转换为MNN模型的阶段。MNN当前支持Tensorflow(Lite)、Caffe、ONNX和TorchScript的模型转换。模型转换工具可以参考[使用说明](../tools/convert.md)。支持转换的算子,可以参考[算子列表文档](../tools/convert.html#id7);在遇到不支持的算子时,可以尝试[自定义算子](../contribute/op.md),或在Github上给我们[提交issue](https://github.com/alibaba/MNN/issues/74)。此外,[模型打印工具](../tools/convert.html#id8)可以用于输出模型结构,辅助调试。除模型转换外,MNN也提供了[模型量化工具](../tools/quant.md),可以对浮点模型进行量化压缩。
1010
### 推理
11-
在端侧加载MNN模型进行推理的阶段。端侧运行库的编译请参考各平台的编译文档:[iOS](../compile/engine.html#ios)[Android](../compile/engine.html#android)[Linux/macOS/Ubuntu](../compile/engine.html#linux-macos)[Windows](../compile/engine.html#windows)。我们提供了[API接口文档](https://github.com/alibaba/MNN/tree/master/doc/API),也详细说明了[会话创建](../inference/session.html#id1)[数据输入](../inference/session.html#id8)[执行推理](../inference/session.html#id17)[数据输出](../inference/session.html#id21)相关的接口和参数。`demo/exec`下提供了使用示例,如图像识别 `demo/exec/pictureRecognition.cpp` ,图像实例分割(人像分割)`demo/exec/segment.cpp`[更多demo](demo.md)。此外,[测试工具](../tools/test.md)[benchmark工具](../tools/benchmark.md)也可以用于问题定位。
11+
在端侧加载MNN模型进行推理的阶段。端侧运行库的编译请参考各平台的编译文档:[iOS](../compile/engine.html#ios)[Android](../compile/engine.html#android)[Linux/macOS/Ubuntu](../compile/engine.html#linux-macos)[Windows](../compile/engine.html#windows)。我们提供了[API接口文档](https://github.com/alibaba/MNN/tree/master/doc/API),也详细说明了[会话创建](../inference/session.html#id1)[数据输入](../inference/session.html#id8)[执行推理](../inference/session.html#id17)[数据输出](../inference/session.html#id21)相关的接口和参数。`demo/exec`下提供了使用示例,如图像识别 `demo/exec/pictureRecognition.cpp` ,图像实例分割(人像分割)`demo/exec/segment.cpp`[更多demo](demo.md)。此外,[测试工具](../tools/test.md)[benchmark工具](../tools/benchmark.md)也可以用于问题定位。

docs/tools/convert.md

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
# 模型转换工具
2-
[从源码编译](../compile/tools.html#id2)
32
## 参数说明
43
```bash
54
Usage:

0 commit comments

Comments
 (0)