TNN API说明文档
TNN:https://github.com/Tencent/TNN
说明文档:https://github.com/Tencent/TNN/blob/master/doc/cn/user/api.md
目录
TNN API说明文档
一、API兼容性
二、API调用
简介
步骤1. 模型解析
步骤2. 网络构建
步骤3. 输入设定
步骤4. 输出获取
二、API详解
API目录结构
1. core/macro.h
2. core/common.h
3. core/status.h
4. core/blob.h
5. core/instance.h
6. core/tnn.h
7. utils/bfp16_utils.h
8. utils/blob_convert.h
9. utils/cpu_utils.h
10. utils/data_type_utils.h
11. utils/dims_vector_utils.h
12. utils/half_utils.h
一、API兼容性
TNN所有对外暴露接口均通过PUBLIC宏显示声明,非暴露接口符号均不可见。
#if defined _WIN32 || defined __CYGWIN__ #ifdef BUILDING_DLL #ifdef __GNUC__ #define PUBLIC __attribute__ ((dllexport)) #else #define PUBLIC __declspec(dllexport) #endif #else #ifdef __GNUC__ #define PUBLIC __attribute__ ((dllimport)) #else #define PUBLIC __declspec(dllimport) #endif #endif #define LOCAL #else #if __GNUC__ >= 4 #define PUBLIC __attribute__ ((visibility ("default"))) #define LOCAL __attribute__ ((visibility ("hidden"))) #else #define PUBLIC #define LOCAL #endif #endif
不同版本API 兼容性遵守语义化版本 2.0.0规则。
二、API调用
简介
API调用主要对模型解析,网络构建,输入设定,输出获取四个步骤进行简要介绍,详细说明参见API详解部分。
步骤1. 模型解析
TNN tnn; TNN_NS::ModelConfig model_config; //proto文件内容存入proto_buffer model_config.params.push_back(proto_buffer); //model文件内容存入model_buffer model_config.params.push_back(model_buffer);
TNN模型解析需配置ModelConfig params参数,传入proto和model文件内容,并调用TNN Init接口即可完成模型解析。
步骤2. 网络构建
TNN_NS::NetworkConfig config; config.device_type = TNN_NS::DEVICE_ARM; TNN_NS::Status error; auto net_instance = tnn.CreateInst(config, error);
TNN网络构建需配置NetworkConfig,device_type可配置ARM, OPENCL, METAL等多种加速方式,通过CreateInst接口完成网络的构建。 华为NPU需要特殊指定network类型以及一个可选的cache路径。cache路径为存om文件的path,如("/data/local/tmp/"),空则表示不存om文件,每次运行都使用IR翻译并从内存读入模型。
config.network_type = TNN_NS::NETWORK_TYPE_HUAWEI_NPU; //Huawei_NPU可选:存om的Cache路径 //add for cache; When using NPU, it is the path to store the om i.e. config.cache_path = "/data/local/tmp/npu_test/"; config.cache_path = "";
步骤3. 输入设定
auto status = instance->SetInputMat(input_mat, input_cvt_param);
TNN输入设定通过调用SetInputMat接口完成,需要传入的数据保存在input_mat中,input_cvt_param可设置scale和bias相关转换参数。
步骤4. 输出获取
auto status = instance->GetOutputMat(output_mat);
TNN输出获取通过调用GetOutputMat接口完成,输出结果将按照特定格式保存在output_mat中。
二、API详解
API目录结构
. └── tnn ├── core │ ├── macro.h # 常用宏定义 │ ├── common.h # 定义常用结构 │ ├── status.h # 接口状态 │ ├── blob.h # 负责数据传递 │ ├── instance.h # 网络实例 │ └── tnn.h # 模型解析 ├── utils │ ├── bfp16_utils.h # bfp16转换工具 │ ├── blob_converter.h # blob输入输出数据工具 │ ├── cpu_utils.h # CPU性能特定优化工具 │ ├── data_type_utils.h # 网络数据类型解析工具 │ ├── dims_vector_utils.h # blob尺寸计算工具 │ └── half_utils.h # fp16转换工具 └── version.h # 编译构建信息
1. core/macro.h
提供不同平台Log宏,不同数据类型最大最小值宏,PUBLIC宏定义,以及部分数据pack转换等宏定义。
2. core/common.h
DataType
:定义不同数据类型枚举值。
DataFormat
:定义Blob Data不同数据排布方式。
NetworkType
:定义不同网络构建类型,默认构建TNN网络,支持第三方库网络构建。
DeviceType
:用于指定网络运行设备及加速方式。
ModelType
:定义模型类型,TNN默认解析模型为TNN模型,同时支持其他第三方库模型格式传入。
typedef enum {
// default
SHARE_MEMORY_MODE_DEFAULT = 0,
// same thread tnn instance share blob memory
SHARE_MEMORY_MODE_SHARE_ONE_THREAD = 1,
// set blob memory from external, different thread share blob memory need
// synchronize
SHARE_MEMORY_MODE_SET_FROM_EXTERNAL = 2
} ShareMemoryMode;
SHARED_MEMORY_MODE_DEFAULT
: 仅支持同一instance不同blob间内存共享 SHARE_MEMORY_MODE_SHARE_ONE_THREAD
: 支持同一线程的不同Instance内存共享 SHARE_MEMORY_MODE_SET_FROM_EXTERNAL
: 支持instance内存由外部传入,共享方式由调用侧决定,线程间共享需处理同步问题,内存分配释放均需调用侧维护。
struct PUBLIC NetworkConfig {
// device type default cpu
DeviceType device_type = DEVICE_NAIVE;
// device id default 0
int device_id = 0;
// blob data format decided by device
DataFormat data_format = DATA_FORMAT_AUTO;
// network type default internal
NetworkType network_type = NETWORK_TYPE_DEFAULT;
// raidnet instances not share memory with others
ShareMemoryMode share_memory_mode = SHARE_MEMORY_MODE_DEFAULT;
// dependent library path
std::vector<std::string> library_path = {};
// compute precision
Precision precision = PRECISION_AUTO;
};
NetworkConfig参数说明:
-
device_type
: 默认为DEVICE_NAIVE
, 不包含特定平台加速指令实现。
- Android使用
DEVICE_ARM
、DEVICE_OPENCL
加速。 - iOS使用
DEVICE_ARM
,DEVICE_METAL
加速。
-
device_id
: 默认为0,多个设备支持通过device_id选择,移动端可不配置。 -
data_format
: 默认为tnn自动选择blob数据排布方式进行加速,可通过此参数设定特定blob数据排布进行加速。 -
network_type
: 支持构建tnn自定义网络以及第三方网络,当前开源版本仅支持构建tnn网络。 -
share_memory_mode
: tnn instance内存共享方式。 -
library_path
: 支持外部依赖库加载,iOS metal kernel库放在app非默认路径需配置此参数。
struct PUBLIC ModelConfig {
ModelType model_type = MODEL_TYPE_TNN;
// tnn model need two params: order is proto content, model content.
// ncnn need two: params: order is param content, bin content.
// openvino model need two params: order is xml content, model path.
// coreml model need one param: coreml model directory path.
// snpe model need one param: dlc model directory path.
// hiai model need two params: order is model name, model file path.
// atlas model need one param: config string.
std::vector<std::string> params;
};
ModelConfig参数说明:
-
model_type
: TNN当前开源版本仅支持传入MODEL_TYPE_TNN
,MODEL_TYPE_NCNN
两种模型格式。 -
params
: TNN模型需传入proto文件内容以及model文件路径。NCNN模型需传入param文件内容以及bin文件路径。
3. core/status.h
Status
定义于status.h头文件中。
enum StatusCode {
TNN_OK = 0x0,
// param errcode
TNNERR_PARAM_ERR = 0x1000,
TNNERR_INVALID_NETCFG = 0x1002,
...
}
class PUBLIC Status {
public:
Status(int code = TNN_OK, std::string message = "OK");
Status &operator=(int code);
bool operator==(int code_);
bool operator!=(int code_);
operator int();
operator bool();
std::string description();
private:
int code_;
std::string message_;
}
当Status code不为TNN_OK,通过description
接口可返回错误描述信息。
4. core/blob.h
// @brief BlobDesc blob data info
struct PUBLIC BlobDesc {
// deivce_type describes devie cpu, gpu, ...
DeviceType device_type = DEVICE_NAIVE;
// data_type describes data precion fp32, in8, ...
DataType data_type = DATA_TYPE_FLOAT;
// data_format describes data order nchw, nhwc, ...
DataFormat data_format = DATA_FORMAT_AUTO;
// DimsVector describes data dims
DimsVector dims;
// name describes the blob name
std::string name;
};
struct PUBLIC BlobHandle {
void *base = NULL;
uint64_t bytes_offset = 0;
};
// @brief Blob tnn data store and transfer interface.
class PUBLIC Blob {
public:
...
//@brief create Blob with blob descript and data handle
Blob(BlobDesc desc, BlobHandle handle);
...
};
Blob当前主要由BlobDesc
以及BlobHandle
构成,其中BlobDesc
描述Blob相关结构信息,BlobHandle
用于读取和存储Blob数据。
BlobDesc
用于描述device_type
, data_type
, data_format
, dims
, name
信息。
dims描述blob维度信息,dims存储尺寸与data_format无关:
- dims尺寸为4,存储尺寸对应N,C,H,W。
- dims尺寸为5,存储尺寸对应N,C,D,H,W。
当前不同平台blob输入输出数据类型及排布如下:
-
ARM
:CPU内存, NC4HW4. -
OPENCL
: GPU显存(clImage), NHC4W4. 其中NH为clImage高,C4W4为clImage宽。 -
METAL
: GPU显存(metal), NC4HW4. - `HUAWEI_NPU: CPU内存, NCHW.
其中最后4代表pack 4, C4代表最后1位4由4个C进行pack。
5. core/instance.h
class PUBLIC Instance {
public:
Instance(NetworkConfig& net_config, ModelConfig& model_config);
~Instance();
// init with model interpeter and inputs shape.
Status Init(std::shared_ptr<AbstractModelInterpreter> interpreter, InputShapesMap inputs_shape);
// deinit, release network
Status DeInit();
// return memory bytes required for forward
Status GetForwardMemorySize(int& memory_size);
// set memory to tnn instance. if success, return status code zero.
// only instance created with SHARE_MEMORY_MODE_SET_FROM_EXTERNAL can be set from external.
// the memory size need >= GetForwardMemorySize().
// releasing or otherwise using the memory for other purposes during the tnn network run
// will result in undefined behavior.
Status SetForwardMemory(void* memory);
// reshape instance with new input shapes
Status Reshape(const InputShapesMap& inputs);
// get tnn command queue
Status GetCommandQueue(void** command_queue);
// @brief tnn instance network infer, it will wait until all layer infer complete.
Status Forward();
...
// tnn instance network infer async.
// device gpu, all layer infer complete will call Callback.
Status ForwardAsync(Callback call_back);
// get all input blobs
Status GetAllInputBlobs(BlobMap& blobs);
// get all output blobs
Status GetAllOutputBlobs(BlobMap& blobs);
// set threads run on cpu
virtual Status SetCpuNumThreads(int num_threads);
...
// set input Mat, if input_name is not set, take the first input as default
Status SetInputMat(std::shared_ptr<Mat> mat,
MatConvertParam param,
std::string input_name = "");
// get output Mat, if output_name is not set, take the first output as default
Status GetOutputMat(std::shared_ptr<Mat>& mat,
MatConvertParam param = MatConvertParam(),
std::string output_name = "",
DeviceType device = DEVICE_ARM, MatType mat_type = NCHW_FLOAT);
};
Instance接口说明:
-
Instance
和Init
接口正常均有TNN CreateInst接口实现调用,用于生成Instance网络实例。 -
GetForwardMemorySize
可获取Instance所有Blob所需内存大小,SetForwardMemory
用于传入外部内存。对于SHARE_MEMORY_MODE_SET_FROM_EXTERNAL
内存模式构建的Instance,内存需由外部传入, 传入内存实际大小不得小于GetForwardMemorySize
返回值大小。 -
Reshape
接口支持重新设定网络输入输出,当前实现Reshape
并不会重新分配内存,所以Reshape
传入尺寸不得大于初始化网络尺寸。 -
GetCommandQueue
接口支持获取网络运行对应的command queue,同一command queue消息顺序执行。 -
GetAllInputBlobs
和GetAllOutputBlobs
分别用于获取输入输出blob。 -
SetCpuNumThreads
可设置CPU线程并行数。 -
Forward
为网络运行同步接口,ForwardAsync
为网络运行异步接口。 -
SetInputMat
用于设定输入Mat,其中MatConvertParam可设定转换参数,对于多输入网络,可用input_name区分。 -
GetOutputMat
用于获取输出结果并保存在输出Mat中,其中MatConvertParam可设定转换参数,对于多输出网络,可用output_name区分,DeviceType可指定输出Mat Memory构建在CPU还是GPU,MatType可用于设定输出Mat数据排列方式。
6. core/tnn.h
class PUBLIC TNN {
public:
...
Status Init(ModelConfig& config);
// denit tnn implement, release model interpreter.
Status DeInit();
// add output to the model.
// if output_name of blob not found, then search output_index of layer.
Status AddOutput(const std::string& output_name, int output_index = 0);
// create tnn network instance with network config and inputs shape.
// if inputs shape not set, use default from model.
std::shared_ptr<Instance> CreateInst(
NetworkConfig& config, Status& status,
InputShapesMap inputs_shape = InputShapesMap());
...
};
TNN接口说明:
- Init接口:负责模型数据传入并解析,需配置并传入ModelConfig。
- DeInit接口: 负责tnn implement释放,默认析构函数可自动释放。
- AddOutput接口:支持增加模型输出,可将网络任意一层输出定义为模型输出。
- CreateInst接口:负责网络实例Instance构建。
7. utils/bfp16_utils.h
接口提供了cpu内存fp32和bfp16转换工具。
8. utils/blob_convert.h
class PUBLIC BlobConverter {
public:
explicit BlobConverter(Blob* blob);
virtual Status ConvertToMat(Mat& image, MatConvertParam param, void* command_queue);
virtual Status ConvertFromMat(Mat& image, MatConvertParam param, void* command_queue);
virtual Status ConvertToMatAsync(Mat& image, MatConvertParam param, void* command_queue);
virtual Status ConvertFromMatAsync(Mat& image, MatConvertParam param, void* command_queue);
private:
Blob* blob_;
std::shared_ptr<BlobConverterAcc> impl_ = nullptr;
};
通过ConvertToMat
可将blob数据按照Mat格式传入Mat,ConvertFromMat
可将Mat数据按照blob格式传入blob, 接口对应的command_queue
可通过 Instance GetCommandQueue
接口获取。
Mat定义于blob_converter.h中,
class PUBLIC Mat {
public:
...
Mat(DeviceType device_type, MatType mat_type, DimsVector shape_dims, void* data);
Mat(DeviceType device_type, MatType mat_type, DimsVector shape_dims);
...
};
其中MatType支持常用的CV输入输出布局,且DeviceType
可设定为CPU,GPU。
typedef enum { INVALID = -1, N8UC3 = 0x00, N8UC4 = 0x01, NGRAY = 0x10, NNV21 = 0x11, NNV12 = 0x12, NCHW_FLOAT = 0x20, } PUBLIC MatType;
同时提供常用预处理,后处理支持,支持设定scale, bias参数设定以及reverse channel适配bgr, rgb等场景。
struct PUBLIC MatConvertParam { std::vector<float> scale = {1.0f, 1.0f, 1.0f, 1.0f}; std::vector<float> bias = {0.0f, 0.0f, 0.0f, 0.0f}; bool reverse_channel = false; };
9. utils/cpu_utils.h
提供CPU线程核绑定以及省电模式设定相关工具。
10. utils/data_type_utils.h
提供DataType尺寸和名称转换相关工具。
11. utils/dims_vector_utils.h
提供常用blob dims计算比较工具。
12. utils/half_utils.h
接口提供了cpu内存fp32和fp16转换工具。