RKNPU2通用API
通用API接口按照异构编程规范,需要将数据拷贝到NPU运行时的内存空间。
通用API部署流程
-
初始化上下文,需要先创建上下文对象和读取模型文件
rknn_context ctx; model = load_model(model_path, &model_len); ret = rknn_init(&ctx, model, model_len, 0, NULL); \\使用opencv读取需要处理的图片,一定要将图片从BGR转换为RGB格式 cv::Mat img = imread(img_path, cv::IMREAD_COLOR); // 读取图片数据,并保存在img cv::cvtColor(img, img, cv::COLOR_BGR2RGB);
-
创建输入
rknn_input inputs[1]; inputs[0].index = 0; inputs[0].type = RKNN_TENSOR_UINT8; inputs[0].size = img.cols*img.rows*img.channels(); inputs[0].fmt = RKNN_TENSOR_NHWC; inputs[0].buf = img.data; // 把img拷贝到inputs[0].buf `` - 设置输入 ```c ret = rknn_inputs_set(ctx, io_num.n_input, inputs); // 把inputs数据拷贝到ctx对象当中
-
执行模型
ret = rknn_run(ctx, nullptr);
-
释放资源
rknn_outputs_release(ctx, 1, outputs); rknn_destroy(ctx); free(model);
RKNPU2零拷贝API
通用API需要利用rknn_inputs_set
设置输入,零拷贝API则直接将数据拷贝到之前申请好的内存即可。
零拷贝API部署流程
-
初始化上下文,需要先创建上下文对象和读取模型文件
rknn_context ctx; model = load_model(model_path, &model_len); ret = rknn_init(&ctx, model, model_len, 0, NULL); \\使用opencv读取需要处理的图片,一定要将图片从BGR转换为RGB格式 cv::Mat img = imread(img_path, cv::IMREAD_COLOR); // 读取图片数据,并保存在img cv::cvtColor(img, img, cv::COLOR_BGR2RGB);
-
创建输入
// 调用rknn_create_mem接口申请内存 input_mems[0] = rknn_create_mem(ctx, input_attrs[0].size_with_stride); ... // 调用rknn_set_io_mem接口让NPU使用已经申请的内存 rknn_set_io_mem(ctx, input_mems[0], &input_attrs[0]);
-
执行模型
ret = rknn_run(ctx, nullptr);
-
释放资源
rknn_destroy_mem(ctx, input_mems[0]); rknn_destroy(ctx); free(model);
速度对比
warmup轮数50,循环推理1000次,计算平均耗时,包括预处理和后处理的总时间。npu只用了一个核心。
型号 | 速度 |
---|---|
通用API | 30-32ms |
零拷贝API | 30-31ms |
来源于https://blog.csdn.net/weixin_43337573/article/details/131817935