Toybrick

楼主: nevin007

[C++ API] 如何使用rknn_init初始化多个模型

nevin007

注册会员

积分
127
 楼主| 发表于 2019-3-7 13:41:05 | 显示全部楼层
protossw512 发表于 2019-3-7 11:40
你好,你在c++运行的时候有发现c++下面跑模型比python下面慢么?

推理速度还好,主要是init时间太长了
回复

使用道具 举报

protossw512

中级会员

积分
252
发表于 2019-3-7 16:36:33 | 显示全部楼层
nevin007 发表于 2019-3-7 13:41
推理速度还好,主要是init时间太长了

我今天专门分别在两边测试了下,发现c++ inference的速度比Python慢差不多一倍。不知道是哪里的问题。。你的c++ api是0.9.3吗?
回复

使用道具 举报

nevin007

注册会员

积分
127
 楼主| 发表于 2019-3-7 16:48:02 | 显示全部楼层
protossw512 发表于 2019-3-7 16:36
我今天专门分别在两边测试了下,发现c++ inference的速度比Python慢差不多一倍。不知道是哪里的问题。。 ...

你好,我用的C++API版本是0.9.3,我测试过它自带的mobilenet-ssd,用SDK自带的测试函数:python约10ms,c++约12ms,你是怎么测试的?
回复

使用道具 举报

protossw512

中级会员

积分
252
发表于 2019-3-8 05:24:29 | 显示全部楼层
nevin007 发表于 2019-3-7 16:48
你好,我用的C++API版本是0.9.3,我测试过它自带的mobilenet-ssd,用SDK自带的测试函数:python约10ms,c ...

奇怪了,我这里直接跑那个rknn_ssd需要22ms。你是在pc上交叉编译好了然后再在3399pro上运行的吗?还是直接在3399pro上编译运行的?我是后者。
回复

使用道具 举报

protossw512

中级会员

积分
252
发表于 2019-3-8 07:09:31 | 显示全部楼层
protossw512 发表于 2019-3-8 05:24
奇怪了,我这里直接跑那个rknn_ssd需要22ms。你是在pc上交叉编译好了然后再在3399pro上运行的吗?还是直 ...

我终于找到原因了,因为我在init的时候加了RKNN_FLAG_COLLECT_PERF_MASK的flag,所以速度会变慢。。。然而不用加也能够测试速度。
回复

使用道具 举报

nevin007

注册会员

积分
127
 楼主| 发表于 2019-3-8 09:21:17 | 显示全部楼层
protossw512 发表于 2019-3-8 07:09
我终于找到原因了,因为我在init的时候加了RKNN_FLAG_COLLECT_PERF_MASK的flag,所以速度会变慢。。。然而 ...

那你能同时初始化多个模型再做推理么
回复

使用道具 举报

protossw512

中级会员

积分
252
发表于 2019-3-9 05:16:48 | 显示全部楼层
nevin007 发表于 2019-3-8 09:21
那你能同时初始化多个模型再做推理么

我还没试过,项目暂时还没用到多个模型。你是怎么实现的?是同样的rknn_context init多次么? 还是说不同的rknn_context?
回复

使用道具 举报

nevin007

注册会员

积分
127
 楼主| 发表于 2019-3-11 09:30:58 | 显示全部楼层
protossw512 发表于 2019-3-9 05:16
我还没试过,项目暂时还没用到多个模型。你是怎么实现的?是同样的rknn_context init多次么? 还是说不同 ...

不同的context,我试过python可以,c++不行...
回复

使用道具 举报

elooon

注册会员

积分
139
发表于 2019-3-11 16:25:51 | 显示全部楼层
nevin007 发表于 2019-3-11 09:30
不同的context,我试过python可以,c++不行...

I rewrite the official demo to init two models, it works.
just for test,ignore the dirty code.
code:

  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include <fstream>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <queue>
  8. #include <sys/time.h>

  9. #include "rknn_api.h"
  10. #include "opencv2/core/core.hpp"
  11. #include "opencv2/imgproc/imgproc.hpp"
  12. #include "opencv2/highgui/highgui.hpp"

  13. using namespace std;

  14. template <class T>
  15. void get_top_n(T* prediction, int prediction_size, size_t num_results,
  16.                float threshold, std::vector<std::pair<float, int>>* top_results,
  17.                bool input_floating) {
  18.   // Will contain top N results in ascending order.
  19.   std::priority_queue<std::pair<float, int>, std::vector<std::pair<float, int>>,
  20.                       std::greater<std::pair<float, int>>>
  21.       top_result_pq;

  22.   const long count = prediction_size;  // NOLINT(runtime/int)
  23.   for (int i = 0; i < count; ++i) {
  24.     float value;
  25.     if (input_floating)
  26.       value = prediction[i];
  27.     else
  28.       value = prediction[i] / 255.0;
  29.     // Only add it if it beats the threshold and has a chance at being in
  30.     // the top N.
  31.     if (value < threshold) {
  32.       continue;
  33.     }

  34.     top_result_pq.push(std::pair<float, int>(value, i));

  35.     // If at capacity, kick the smallest value out.
  36.     if (top_result_pq.size() > num_results) {
  37.       top_result_pq.pop();
  38.     }
  39.   }

  40.   // Copy to output vector and reverse into descending order.
  41.   while (!top_result_pq.empty()) {
  42.     top_results->push_back(top_result_pq.top());
  43.     top_result_pq.pop();
  44.   }
  45.   std::reverse(top_results->begin(), top_results->end());
  46. }

  47. int ReadLabelsFile(const string& file_name,
  48.                             std::vector<string>* result,
  49.                             size_t* found_label_count) {
  50.   std::ifstream file(file_name);
  51.   if (!file) {
  52.     std::cerr << "Labels file " << file_name << " not found\n";
  53.     return -1;
  54.   }
  55.   result->clear();
  56.   string line;
  57.   while (std::getline(file, line)) {
  58.     result->push_back(line);
  59.   }
  60.   *found_label_count = result->size();
  61.   const int padding = 16;
  62.   while (result->size() % padding) {
  63.     result->emplace_back();
  64.   }
  65.   return 0;
  66. }

  67. int main(int argc, char** argv)
  68. {
  69.     const char *img_path = "/home/toybrick/work/test/tmp/dog.jpg";
  70.     const char *model_path = "/home/toybrick/work/test/tmp/mobilenet_v1-tf.rknn";
  71.     const char *model_path2 = "/home/toybrick/work/test/tmp/mobilenet_ssd.rknn";
  72.     const char *lable_path = "/home/toybrick/work/test/tmp/labels.txt";
  73.     const int output_elems = 1001;

  74.     const int img_width = 224;
  75.     const int img_height = 224;
  76.     const int img_channels = 3;

  77.     const int input_index = 0;      // node name "input"
  78.     const int output_index = 0;     // node name "MobilenetV1/Predictions/Reshape_1"

  79.     // Load image
  80.     cv::Mat img = cv::imread(img_path, 1);
  81.     if(!img.data) {
  82.         printf("cv::imread %s fail!\n", img_path);
  83.         return -1;
  84.     }
  85.     if(img.cols != img_width || img.rows != img_height)
  86.         cv::resize(img, img, cv::Size(img_width, img_height), (0, 0), (0, 0), cv::INTER_LINEAR);

  87.     //BGR->RGB
  88.     cv::cvtColor(img, img, cv::COLOR_BGR2RGB);

  89.     // Load model
  90.     FILE *fp = fopen(model_path, "rb");
  91.     if(fp == NULL) {
  92.         printf("fopen %s fail!\n", model_path);
  93.         return -1;
  94.     }
  95.     fseek(fp, 0, SEEK_END);
  96.     int model_len = ftell(fp);
  97.     void *model = malloc(model_len);
  98.     fseek(fp, 0, SEEK_SET);
  99.     if(model_len != fread(model, 1, model_len, fp)) {
  100.         printf("fread %s fail!\n", model_path);
  101.         free(model);
  102.         return -1;
  103.     }

  104.     // Start Inference
  105.     rknn_input inputs[1];
  106.     rknn_output outputs[1];
  107.     rknn_tensor_attr output0_attr;

  108.     int ret = 0;
  109.     void *model2;
  110.     rknn_context ctx1 = 0;
  111.     rknn_context ctx2 = 0;

  112.     ret = rknn_init(&ctx1, model, model_len, RKNN_FLAG_PRIOR_MEDIUM);
  113.     if(ret < 0) {
  114.         printf("rknn_init fail! ret=%d\n", ret);
  115.         goto Error;
  116.     }

  117.     printf("rknn_init 1 succeed! ret=%d\n", ret);

  118.     fclose(fp);
  119.     model_len = 0;

  120.     // Load model
  121.     fp = fopen(model_path2, "rb");
  122.     if(fp == NULL) {
  123.         printf("fopen %s fail!\n", model_path);
  124.         return -1;
  125.     }
  126.     fseek(fp, 0, SEEK_END);
  127.     model_len = ftell(fp);
  128.     model2 = malloc(model_len);
  129.     fseek(fp, 0, SEEK_SET);
  130.     if(model_len != fread(model2, 1, model_len, fp)) {
  131.         printf("fread %s fail!\n", model_path2);
  132.         free(model2);
  133.         return -1;
  134.     }

  135.     ret = rknn_init(&ctx2, model2, model_len, RKNN_FLAG_PRIOR_MEDIUM);
  136.     if(ret < 0) {
  137.         printf("rknn_init fail! ret=%d\n", ret);
  138.         goto Error;
  139.     }

  140.     printf("rknn_init 2 succeed! ret=%d\n", ret);

  141.     output0_attr.index = 0;
  142.     ret = rknn_query(ctx1, RKNN_QUERY_OUTPUT_ATTR, &output0_attr, sizeof(output0_attr));
  143.     if(ret < 0) {
  144.         printf("rknn_query fail! ret=%d\n", ret);
  145.         goto Error;
  146.     }

  147.     inputs[0].index = input_index;
  148.     inputs[0].buf = img.data;
  149.     inputs[0].size = img_width * img_height * img_channels;
  150.     inputs[0].pass_through = false;
  151.     inputs[0].type = RKNN_TENSOR_UINT8;
  152.     inputs[0].fmt = RKNN_TENSOR_NHWC;
  153.     ret = rknn_inputs_set(ctx1, 1, inputs);
  154.     if(ret < 0) {
  155.         printf("rknn_input_set fail! ret=%d\n", ret);
  156.         goto Error;
  157.     }

  158.     ret = rknn_run(ctx1, nullptr);
  159.     if(ret < 0) {
  160.         printf("rknn_run fail! ret=%d\n", ret);
  161.         goto Error;
  162.     }

  163.     outputs[0].want_float = true;
  164.     outputs[0].is_prealloc = false;
  165.     ret = rknn_outputs_get(ctx1, 1, outputs, nullptr);
  166.     if(ret < 0) {
  167.         printf("rknn_outputs_get fail! ret=%d\n", ret);
  168.         goto Error;
  169.     }

  170.     // Process output
  171.     if(outputs[0].size == output0_attr.n_elems * sizeof(float))
  172.     {
  173.         const size_t num_results = 5;
  174.         const float threshold = 0.001f;

  175.         std::vector<std::pair<float, int>> top_results;
  176.         get_top_n<float>((float*)outputs[0].buf, output_elems,
  177.                            num_results, threshold, &top_results, true);

  178.         std::vector<string> labels;
  179.         size_t label_count;
  180.         if (!ReadLabelsFile(lable_path, &labels, &label_count)) {
  181.             for (const auto& result : top_results) {
  182.                 const float confidence = result.first;
  183.                 const int index = result.second;
  184.                 std::cout << confidence << ": " << index << " " << labels[index] << "\n";
  185.             }
  186.         }
  187.     }
  188.     else
  189.     {
  190.         printf("rknn_outputs_get fail! get output_size = [%d], but expect %u!\n",
  191.             outputs[0].size, (uint32_t)(output0_attr.n_elems * sizeof(float)));
  192.     }

  193.     rknn_outputs_release(ctx1, 1, outputs);

  194. Error:
  195.     if(ctx1 > 0)        rknn_destroy(ctx1);
  196.     if(model)           free(model);
  197.     if(fp)              fclose(fp);
  198.     return 0;
  199. }
复制代码
回复

使用道具 举报

elooon

注册会员

积分
139
发表于 2019-3-11 16:29:43 | 显示全部楼层
outputs:

[toybrick@localhost build]$ ./rknn_mobilenet
rknn_init 1 succeed! ret=0
rknn_init 2 succeed! ret=0
0.842285: 156 Shih-Tzu
0.0474243: 155 Pekinese
0.0256042: 188 Yorkshire terrier
0.0138168: 205 Lhasa
0.00746155: 263 Brabancon griffon
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

产品中心 购买渠道 开源社区 Wiki教程 资料下载 关于Toybrick


快速回复 返回顶部 返回列表