Toybrick

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

nevin007

注册会员

积分
127
楼主
发表于 2019-3-5 15:34:56    查看: 26340|回复: 24 | [复制链接]    打印 | 显示全部楼层
本帖最后由 nevin007 于 2019-3-7 17:39 编辑

rknn_init初始化模型时间长,当需要运行2个以上模型的时候,应该是将所有的模型统一做初始化。

但是我试着初始化两个rknn模型,使用C++API,定义两个context,运行时会报错:load model done.
rknn_init fail! ret=-6
即第一个模型可以初始化成功,第二个模型会初始化失败!
--------------------------------------------------------------------------------------------------------------

回复中有说使用Python_API可以同时初始化多个模型,我试了下确实可以,但是使用C++_API确实不行...
希望官方能确认下是使用的问题还是C++_API的问题,非常感谢!


回复

使用道具 举报

nevin007

注册会员

积分
127
沙发
 楼主| 发表于 2019-3-5 18:01:13 | 显示全部楼层
seedlin 发表于 2019-3-5 17:50
车牌识别的那个人写的就是2个模型同时运行的,你init必须是2个对象,你不会只创建一个rknn对象,然后init两 ...

我用的是c++的API,在init前好像只有加载rknn模型的操作
回复

使用道具 举报

nevin007

注册会员

积分
127
板凳
 楼主| 发表于 2019-3-6 09:57:55 | 显示全部楼层
elooon 发表于 2019-3-5 19:54
你是只分配了一个rknn_context变量,然后对这个变量执行了两次init?


int load_model(std::vector<const char *>& net,
                std::vector<rknn_context> &ctx)
{
    FILE *fp;
    int model_len=0;
    int ret = 0;
    rknn_context context=0;
    rknn_context context_2=0;

    // load rknn model1
    fp = fopen(net[0], "rb");
    if(fp == NULL) {
        printf("fopen %s fail!\n", net[0]);
        return -1;
    }
    fseek(fp, 0, SEEK_END);
    model_len = ftell(fp);               
    model_net_1 = malloc(model_len);         
    fseek(fp, 0, SEEK_SET);
    if(model_len != fread(model_net_1, 1, model_len, fp)) {
        printf("fread %s fail!\n", net[0]);
        free(model_net_1);
        return -1;
    }
    printf("model_len:%d\n",model_len);

    // rknn_init
    ret = rknn_init(&context, model_net_1, model_len, RKNN_FLAG_PRIOR_MEDIUM);                    
    if(ret < 0) {
        printf("rknn_init fail! ret=%d\n", ret);
        source_release(context, model_net_1);
        return -1;
    }
    ctx.push_back(context);
    printf("[debug] ctx[0]:%ld\n",context);
    fclose(fp);
    model_len = 0;


    // load rknn model2
    fp = fopen(net[1], "rb");
    if(fp == NULL) {
        printf("fopen %s fail!\n", net[1]);
        return -1;
    }
    fseek(fp, 0, SEEK_END);
    model_len = ftell(fp);               
    model_net_2 = malloc(model_len);         
    fseek(fp, 0, SEEK_SET);
    if(model_len != fread(model_net_2, 1, model_len, fp)) {
        printf("fread %s fail!\n", net[1]);
        free(model_net_2);
        return -1;
    }
    printf("model_len:%d\n",model_len);

    // rknn_init
    ret = rknn_init(&context_2, model_net_2, model_len, RKNN_FLAG_PRIOR_MEDIUM);                    
    if(ret < 0) {
        printf("rknn_init fail! ret=%d\n", ret);
        source_release(context_2, model_net_2);
        return -1;
    }
    ctx.push_back(context_2);
    printf("[debug] ctx[1]:%ld\n",context_2);
    fclose(fp);

    free(model_net_1);
    free(model_net_2);
    return 0;
}




我定义了2个context,运行后错误信息如下:
model_len:17347
[debug] ctx[0]:416131600
model_len:17350
rknn_init fail! ret=-6
ctx.size:1

只能注册一个模型...


回复

使用道具 举报

nevin007

注册会员

积分
127
地板
 楼主| 发表于 2019-3-6 10:30:45 | 显示全部楼层
yhc 发表于 2019-3-6 10:25
请问单独初始化第二个模型可以吗

可以的,单独运行上半部分或者下半部分都没有问题
回复

使用道具 举报

nevin007

注册会员

积分
127
5#
 楼主| 发表于 2019-3-6 11:39:46 | 显示全部楼层
本帖最后由 nevin007 于 2019-3-6 11:45 编辑
yhc 发表于 2019-3-6 10:51
-6是报RKNN_ERR_MODEL_INVALID,17350确定是第二个模型的大小是吗,有没有读错文件什么的呢 ...

是的,模型我都单独运行过,没有问题...不会是同时只能有一个ctx吧...
灰掉上半部分,初始化下半部分是正常的:
model_len:17350
[debug] ctx[1]:595593744
ctx.size:1

就是不能两个同时初始化...

回复

使用道具 举报

nevin007

注册会员

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

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

使用道具 举报

nevin007

注册会员

积分
127
7#
 楼主| 发表于 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,你是怎么测试的?
回复

使用道具 举报

nevin007

注册会员

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

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

使用道具 举报

nevin007

注册会员

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

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

使用道具 举报

nevin007

注册会员

积分
127
10#
 楼主| 发表于 2019-3-12 10:22:11 | 显示全部楼层
elooon 发表于 2019-3-11 16:29
outputs:

[toybrick@localhost build]$ ./rknn_mobilenet

非常感谢!我测试了你的Demo,确实可以跑通。在此基础上,我进一步做了几个测试:
1、将model_path2(ctx2)替换成MTCNN中的RNet和ONet,结果也都可以同时初始化;
2、将model_path2(ctx2)替换成MTCNN中的PNet,运行时仍然会报错:
rknn_init 1 succeed! ret=0
rknn_init fail! ret=-6
3、在对PNet做模型转换时,设置do_quantization=False,即不做量化,替换第2步中的模型再次执行,结果可以正常初始化!
综上测试,可以看出,C++API支持初始化多个模型,但对于少数模型(如PNet这种全卷积网络)仅支持非量化的模型...
回复

使用道具 举报

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

本版积分规则

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


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