【Android-NCNN-Vulkan】记录一次ncnn-vulkan在低性能开发板上出现的native内存溢出的问题

    技术2022-07-11  79

    模型作用:人脸关键点检测

    原模型:tensorflow pb.model

    转化后:ncnn *.param *.model

    主干网络:shufflenet v2

    CPU:ARM A53 2.0GHz 2G MEM

    GPU:IMG GE 8300

    问题描述:

    加载两个模型--人脸检测和人脸关键点检测 人脸检测模型:ssd,param 10kb,model 509kb,cpu load param 需要1.7ms,load model 需要 19ms; 但是,使用vulkan load param 需要 32s,load model需要55s,一个初始化需要将近2min;

    人脸关键点检测模型:shufflenet v2,param 40kb, model 2.5Mb, cpu load param 需要 5ms,load model 需要 10ms; 但是,使用vulkan load param 需要32s,load model时,mem 中native 狂飙,直接被杀死,导致初始化失败。

    内存泄漏问题描述:

    主干采用shufflenet v2,最后三层为reduce,由于vulkan不支持reduce,因此用如下方法代替

    Pooling pool1 1 1 concat_splitncnn_0 pool1 0=1 1=20 11=20 2=20 12=20 5=1

    但是在vulkan ncnn load model 执行到 pipeline.cpp 469行

    VkResult ret = vkCreateComputePipelines(vkdev->vkdevice(), 0, 1, &computePipelineCreateInfo, 0, &pipeline);

    内存崩掉了,然后被系统强杀。

     

    内存泄漏原因分析:

    0=1 表示average pool,1和11表示kernal的h和w,2和12表示pad的h和w,以此来代替reduce操作,该方法在ncnn arm cpu 上能够得到正确的结果,但是在vulkan gpu上内存会出现上述问题。

    内存泄漏替换方案:

    Pooling pool1 1 1 concat_splitncnn_0 pool1 0=1 4=1

    可以在确保正确forward的同时,在该硬件环境上推理速度上升30ms。

     

    load model速度慢问题,参见 【Android-NCNN-Vulkan】ncnn-vulkan load param & model 速度慢。

     

    【PS】复现vulkan average pooling 内存溢出问题:

    pool.proto

    7767517 2 2 Input images 0 1 images 0=13 1=13 2=1024 Pooling pool1 1 1 images pool1 0=1 1=12 11=12 2=12 12=12 5=1 unsigned char m[16]; std::string param = "/pool.proto"; Net->load_param(param.c_str()); Net->load_model(m);

    设置kernal 和 stride  >=13 时,在本次记录的配置中,出现内存溢出

    详细问题参见:https://github.com/Tencent/ncnn/issues/1874

    Processed: 0.011, SQL: 9