天天看點

【Android-NCNN-Vulkan】記錄一次ncnn-vulkan在低性能開發闆上出現的native記憶體溢出的問題

【Android-NCNN-Vulkan】記錄一次ncnn-vulkan在低性能開發闆上出現的native記憶體溢出的問題

模型作用:人臉關鍵點檢測

原模型: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