NNPack 使用教程

来源:互联网 发布:gta5联机mod端口 编辑:程序博客网 时间:2024/05/29 07:58

NNPack 使用教程

NNPACK 编译 (Linux OS)

前提:

(1)安装libffi-dev

(2)安装libpython2.7-dev

(3)安装libgit2   http://www.pygit2.org/install.html

(4)安装python-pycurl libcurl4-openssl-dev

(5)安装python-libssh2 libssh2-1-dev

(6)apt-get install python-yaml



1、安装ninja system

[cpp] view plain copy
  1. apt-get install ninja-build   
  2. apt-get install ninja    
  3. pip install ninja-syntax   

2、编译安装 PeachPy

[cpp] view plain copy
  1. pip install --upgrade git+https://github.com/Maratyszcza/PeachPy  
  2. pip install --upgrade git+https://github.com/Maratyszcza/confu  


3、下载编译NNPACK

[cpp] view plain copy
  1. git clone https://github.com/Maratyszcza/NNPACK.git    
  2. cd NNPACK   
  3. confu setup  
  4. python ./configure.py    
  5. ninja   
NNPACK详解
一:NNPACK简介
NNPACK由facebook开发,是一个加速神经网络计算的加速包,NNPACK可以在多核CPU平台上提高卷积层计算性能NNPACK采用的快速卷积算法是基于Fourier transform 和 Winograd transform算法


二:前向计算的性能
如下图(Intel Core i7 6700K vs BVLC Caffe master branch)
链接:https://github.com/Maratyszcza/NNPACK
LibraryCaffeNNPACKNNPACKNNPACKAlgorithmim2col + sgemmFFT-8x8FFT-16x16Winograd F(6x6, 3x3)AlexNet:conv2315 ms129 ms86 msN/AAlexNet:conv3182 ms87 ms44 ms70 msAlexNet:conv4264 ms109 ms56 ms89 msAlexNet:conv5177 ms77 ms40 ms64 msVGG-A:conv1255 ms303 ms260 ms404 msVGG-A:conv2902 ms369 ms267 ms372 msVGG-A:conv3.1566 ms308 ms185 ms279 msVGG-A:conv3.21091 ms517 ms309 ms463 msVGG-A:conv4.1432 ms228 ms149 ms188 msVGG-A:conv4.2842 ms402 ms264 ms329 msVGG-A:conv5292 ms141 ms83 ms114 msOverFeat:conv2424 ms158 ms73 msN/AOverFeat:conv3250 ms69 ms74 ms54 msOverFeat:conv4927 ms256 ms272 ms173 msOverFeat:conv51832 ms466 ms524 ms315 ms

三:NNPACK支持的层
  • 卷积层 (Convolutional layer
  • 全连接层 (Fully-connected layer
  • 池化层 (Max pooling layer
  • ReLU layer
  • Softmax layer

四:NNPACK 编译 (Linux OS)
1、编译安装 PeachPy
[cpp] view plain copy
  1. git clone https://github.com/Maratyszcza/PeachPy.git  
  2. cd PeachPy  
  3. [sudo] pip install --upgrade -r requirements.txt  
  4. python setup.py generate  
  5. [sudo] pip install --upgrade .  

2、安装ninja 和 ninja-syntax python模块
[cpp] view plain copy
  1. sudo apt-get install ninja-build || brew install ninja  
  2. [sudo] pip install ninja-syntax  

3、下载编译NNPACK
[cpp] view plain copy
  1. git clone --recursive https://github.com/Maratyszcza/NNPACK.git  
  2. cd NNPACK  
  3. python ./configure.py  
  4. ninja  
注意:
编译nnpack过程如果出现一些找不到头文件等情况,一般是需要下载第三方库。在nnpack的包中有对于的目录third-party,分别下载,放到对应得目录中,并分别编译。
FXdiv @ ba65e0d:https://github.com/Maratyszcza/FXdiv/tree/ba65e0de6c48d91be1cd578755f6db172774fe53
gtest-1.7.0 @ c994585
https://github.com/google/googletest/tree/c99458533a9b4c743ed51537e25989ea55944908
pthreadpool @ 17747d7
https://github.com/Maratyszcza/pthreadpool/tree/17747d7ef2d54dc15af63f9d05a261e04526ba5d

四:测试
NNPACK编译完成之后,在NNPACK-master/bin目录下有测试卷积、全连接等可执行程序。
例如,测试卷积输入通道 16 ,输出通道 16 , 输入图像180*180,kernel 3*3 ,迭代100次,


执行结果:


五、使用NNPACK 实现卷积
  • input channels: 1
  • output channels:1
  • input size:4*4
  • kernel size:3*3


1、代码(conv_nnpack.c)

[cpp] view plain copy
  1. #include<stdio.h>  
  2. #include<string.h>  
  3. #include<stdlib.h>  
  4. #include<unistd.h>  
  5. #include<sys/time.h>  
  6. #include<nnpack.h>  
  7. int main(int argc , char** argv)  
  8. {  
  9.     //init nnpack  
  10.     enum nnp_status init_status = nnp_initialize();  
  11.     if (init_status != nnp_status_success) {  
  12.         fprintf(stderr, "NNPACK initialization failed: error code %d\n", init_status);  
  13.         exit(EXIT_FAILURE);  
  14.     }  
  15.   
  16.         enum nnp_convolution_algorithm algorithm = nnp_convolution_algorithm_auto;  
  17.         const size_t batch_size = 1;  
  18.         const size_t input_channels = 1;  
  19.         const size_t output_channels = 1;  
  20.         const struct nnp_padding input_padding = { 0, 0, 0, 0 };  
  21.         const struct nnp_size input_size ={ 4, 4 };  
  22.         const struct nnp_size kernel_size = { 3, 3 },;  
  23.         const struct nnp_size output_size = {  
  24.                 .width = (input_padding.left + input_size.width + input_padding.right - kernel_size.width) / output_subsampling.width + 1,  
  25.                 .height = (input_padding.top + input_size.height + input_padding.bottom - kernel_size.height) / output_subsampling.height + 1  
  26.         };  
  27.     int iter=1;  
  28.   
  29.     //malloc memory for input, kernel, output, bias  
  30.     float* input = (float*)malloc(batch_size * input_channels *input_size.height *input_size.width * sizeof(float));  
  31.     float* kernel = (float*)malloc(input_channels * output_channels * kernel_size.height * kernel_size.width * sizeof(float));  
  32.     float* output = (float*)malloc(batch_size* output_channels * output_size.height * output_size.width * sizeof(float));  
  33.     float* bias = (float*)malloc(output_channels * sizeof(float));  
  34.   
  35.     pthreadpool_t threadpool=NULL;  
  36.     //flase:only one thread, true: mutiple threads   
  37.     if (false) {   
  38.                 threadpool = pthreadpool_create(options.threads);  
  39.                 printf("Threads: %zu\n", pthreadpool_get_threads_count(threadpool));  
  40.     }  
  41.   
  42.     struct nnp_profile computation_profile;//use for compute time;  
  43.     //init input data  
  44.     int i,j;  
  45.     for(int c=0; c<input_channels;c++ ){  
  46.         for(i=0; i<input_size.height; i++){  
  47.             for(j=0; j<input_size.width; j++){  
  48.                 input[c*input_size.height*input_size.width+i*input_size.width+j] = (i*input_size.width+j)*1.0;  
  49.             }  
  50.         }  
  51.     }  
  52.   
  53.     //init kernel data  
  54.     for(int i=0; i<output_channels;i++ ){  
  55.         for(j=0; j<input_channels*kernel_size.height*kernel_size.width; j++){  
  56.             kernel[i*input_channels*kernel_size.height*kernel_size.width+j] = 1.0;            
  57.         }  
  58.     }  
  59.   
  60.     //init bias data  
  61.     for(int i=0; i<output_channels;i++ ){  
  62.         bias[i] = 1.0;  
  63.     }  
  64.   
  65.     //execute conv  
  66.     struct timeval conv_start;  
  67.     struct timeval conv_end;  
  68.     gettimeofday(&conv_start,NULL);  
  69.     for(int i=0;i<iter;i++){  
  70.         nnp_convolution_output(algorithm,  
  71.                     batch_size,  
  72.                     input_channels,  
  73.                     output_channels,  
  74.                     input_size,  
  75.                     input_padding,  
  76.                     kernel_size,  
  77.                     input,  
  78.                     kernel,  
  79.                     bias,  
  80.                     output,  
  81.                     threadpool,  
  82.                     &computation_profile);  
  83.     }  
  84.     gettimeofday(&conv_end,NULL);  
  85.     //printf ouput data  
  86.     for(i=0;i<output_channels; i++){  
  87.         for(j=0;j<output_size.height*output_size.width; j++){  
  88.             printf("%f\t",output[i*output_size.height*output_size.width+j]);      
  89.         }  
  90.         printf("\n");     
  91.     }  
  92.     float conv_time_use = 1000.0*(float)(conv_end.tv_sec-conv_start.tv_sec)+(float)(conv_end.tv_usec-conv_start.tv_usec)/1000.0;  
  93.     printf("conv Time use = %f(ms)\n",conv_time_use);  
  94.     printf("conv mean Time use = %f(ms) / iter\n",conv_time_use/iter);  
  95.     return 0;  
  96. }  

2、编译


编译,要链接 -lnnpack-lphterad。-lphterad是第三方库pthreadpool使用pthread创建线程,pthreadpool是根据平台CPU的核数,创建对应数量的线程。此处代码false使用一个线程。

3、输出结果:


六:NNPACK与 im2col+sgemm卷积性能对比
  • im2col+sgemm使用openblas
  • intput channels : 16
  • output channels :16
  • input size : 360*360
  • kernel size: 2*2 , 3*3, 5*5
如下图:

图 nnpack vs im2col_segemm

 23510nnpack6.69ms7.38ms9.71ms26.44msim2col_sgemm37.83ms86.95ms236.91ms929.66ms
表 nnpack vs im2col_segemm

原创粉丝点击