推理框架现状和痛点
现在业界尚不存在各方面都远超其同类产品的推理框架,不同推理引擎在不同平台,硬件和模式下分别具有各自的优势,比如TensorRT有足够多的灵活性,在GPU执行时可以共享上下文,可以使用外部内存用于推理等,OpenVINO有高吞吐率模式,可以CPU与GPU异构设备同时推理,TNN提供给上层用户直接操作其内部分配的输入输出Blob的能力等,另外其他推理框架也都有其各自的特性,需要足够尊重以及了解这些推理框架,才能不丢失每一个推理框架的特性,并做到统一的使用的体验。但作为模型部署工程师,为了实现最优效率,如果针对不同环境都写一套代码去适配其最优推理框架,其耗费的学习成本和精力及代码量都将极其巨大。
随着AI技术的迅速发展,各种AI应用如雨后春笋般涌现。为了更好地满足多终端深度学习应用的需求,我们自豪地宣布,全栈式多终端模型部署框架 nndeploy 正式开源!这一框架的使命是简化和加速深度学习模型在不同设备上的运行,为包括智能手机、智能家居设备、自动驾驶汽车、工业设备、大模型推理等多样化应用场景提供更灵活、高效的解决方案。
为什么选择 nndeploy?
使用范例
以检测模型demo为例 - demo\detect\demo.cc
+ 创建检测模型有向无环图pipeline
// 检测模型的有向无环图pipeline名称,例如:
// NNDEPLOY_YOLOV5/NNDEPLOY_YOLOV6/NNDEPLOY_YOLOV8
std::string name = demo::getName();
// 推理后端类型,例如:
// kInferenceTypeOpenVino/kInferenceTypeTensorRt/kInferenceTypeOnnxRuntime/...
base::InferenceType inference_type = demo::getInferenceType();
// 推理设备类型,例如:
// kDeviceTypeCodeX86:0/kDeviceTypeCodeCuda:0/...
base::DeviceType device_type = demo::getDeviceType();
// 模型类型,例如:
// kModelTypeOnnx/kModelTypeMnn/...
base::ModelType model_type = demo::getModelType();
// 模型是否是路径
bool is_path = demo::isPath();
// 模型路径或者模型字符串
std::vector<std::string> model_value = demo::getModelValue();
// 有向无环图pipeline的输入边packert
model::Packet input("detect_in");
// 有向无环图pipeline的输出边packert
model::Packet output("detect_out");
// 创建检测模型有向无环图pipeline
model::Pipeline *pipeline =
model::createPipeline(name, inference_type, device_type, &input, &output,
model_type, is_path, model_value);
if (pipeline == nullptr) {
NNDEPLOY_LOGE("pipeline is nullptr");
return -1;
}
+ 初始化有向无环图pipeline
base::Status status = pipeline->init();
if (status != base::kStatusCodeOk) {
NNDEPLOY_LOGE("pipeline init failed");
return -1;
}
```
+ 给有向无环图pipeline写入输入边输出边
```c++
// 有向无环图pipeline的输入图片路径
std::string input_path = demo::getInputPath();
// opencv读图
cv::Mat input_mat = cv::imread(input_path);
// 将图片写入有向无环图pipeline输入边
input.set(input_mat);
// 定义有向无环图pipeline的输出结果
model::DetectResult result;
// 将输出结果写入有向无环图pipeline输出边
output.set(result);
+ 有向无环图pipeline运行
status = pipeline->run();
if (status != base::kStatusCodeOk) {
NNDEPLOY_LOGE("pipeline run failed");
return -1;
}
+ 有向无环图pipeline反初始化
status = pipeline->deinit();
if (status != base::kStatusCodeOk) {
NNDEPLOY_LOGE("pipeline deinit failed");
return -1;
}
+ 有向无环图pipeline销毁
delete pipeline;
未来计划