作者:Gu, Jianjun
clCaffe编译与配置
Intel clCaffe (https://github.com/01org/caffe)是利用基于Intel Skylake及以后的处理器核显(即Gen9架构以上)做硬件加速的一个修改版。如果你当前机器是基于Nvdia显卡,请用NV cuda加速版本;如果你的显卡是AMD的,请check out 官方BVLC caffe的opencl分支。
clCaffe的编译
安装编译所需要的软件
- Visual Studio 2015
- Anaconda + Python 64位版本 https://www.anaconda.com
- cmake-3.9.3-win64-x64 https://cmake.org/
- Git-2.14.2-64-bit https://git-scm.com/
- Intel SDK for OpenCL for Windows* https://software.intel.com/zh-cn/intel-opencl
- 最新的Intel 显卡驱动 https://www.intel.com/content/www/cn/zh/support/products/80939/graphics-drivers.html
配置Windows*的环境变量
为了避免等会CMAKE生成编译脚本的时候找不到一些依赖关系,有的没的路径都加一些,包括Cmake, Git, Ananconda以及Python的路径。(环境变量的配置同上篇文章的2.2部分 )
Image may be NSFW.
Clik here to view.
下载和编译Intel clCaffe工程
clCaffe的编译过程和caffe基本类似。不同的是clCaffe所需的caffe-builder的libraries目录是放在clCaffe自己目录的build目录下,同时额外多下载编译了一些支持openCL运行的开源项目。为了简单起见,这里参考了一个开源项目里的编译脚本https://github.com/liyuming1978/caffe_example/blob/master/install_scripts/Windows_install/build-clcaffe.cmd
首先先创建一个clcaffe-windows的目录,下面提供了一个简单的编译脚本build-clcaffe.cmd(为了简化clCaffe的编译过程,这里直接提供了完整的编译脚本,不再解释脚本里每一步的具体目的,有兴趣的开发者可以自己研究修改脚本来满足自己的需求),在clcaffe-windows目录下创建并且执行这个批处理脚本文件。这个脚本是根据我自己的环境 Win10+VS2015+Python3.6写的,如果你的开发环境跟我的不同,比如是python2.7或者3.5,需要按照脚本里的注释做相应的修改。
@echo off @setlocal EnableDelayedExpansion echo must install openclsdk,python(anaconda),git,cmake,vs 2015 for desktop ::设置python所在路径, 基于python3, ::如果编译环境是python2, 需要修改下面print()这句话,按照python2的语法格式修改 for /f "delims=" %%t in ('python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"') do set py_path_str=%%t ::下载并编译clCaffe所需要的一些依赖项目 cd %~sdp0 git clone https://github.com/dlfcn-win32/dlfcn-win32 cd dlfcn-win32 cmake -G "Visual Studio 14 2015 Win64" . cmake --build . --config Release cd %~sdp0 ::git clone https://github.com/ptillet/isaac.git (isaac build wrong, please use intel isaac) git clone https://github.com/intel/isaac.git cd isaac mkdir build cd build cmake -G "Visual Studio 14 2015 Win64" .. cmake --build . --config Release ::下载clCaffe的项目 cd %~sdp0 git clone https://github.com/01org/caffe.git cd caffe git checkout inference-optimize git pull git clone https://github.com/viennacl/viennacl-dev.git ::下面这部分是拷贝自己编译的caffe-builder的libraries到clCaffe的目录里,同时编译时需要 ::修改WindowsDownloadPrebuiltDependencies.cmake,注释掉对应的网络下载和解压缩代码 ::防止WindowsDownloadPrebuiltDependencies.cmake脚本报找不到网上对应的caffe-builder包, :: 如果编译环境是python2.7或者3.5, 可以注释掉下面这段代码, 编译脚本会自动从网上下载预编译好的依赖库 cd %~sdp0 cd caffe mkdir build cd .\build mkdir libraries cd .. xcopy C:\work\caffe-builder-1.1.0\build_v140_x64\libraries .\build\libraries /s /h /c /y ::设置编译参数,开始编译clCaffe cd %~sdp0 cd caffe set BUILD_PYTHON=1 set BUILD_PYTHON_LAYER=1 set USE_INTEL_SPATIAL=1 set USE_GREENTEA=1 set USE_ISAAC=1 set RUN_TESTS=0 set RUN_INSTALL=1 set PYTHON_VERSION=3 call scripts\build_win.cmd echo "clCaffe compile done"
注意事项:
编译过程中会报一次错,错误为找不到caffe/proto/caffe.pb.h
Image may be NSFW.
Clik here to view.
这个错误不是本机编译环境的问题,而是因为这个项目还不完善,在Windows*下编译项目的顺序有些问题。在Windows*下在编译pretune_convert.vcxproj的时候,这个caffe.pb.h还没有生成。
解决办法也很简单,直接再执行一遍build-clcaffe.cmd中下图的这部分脚本即可。
::设置编译参数,开始编译clCaffe cd %~sdp0 cd caffe set BUILD_PYTHON=1 set BUILD_PYTHON_LAYER=1 set USE_INTEL_SPATIAL=1 set USE_GREENTEA=1 set USE_ISAAC=1 set RUN_TESTS=0 set RUN_INSTALL=1 set PYTHON_VERSION=3 call scripts\build_win.cmd
最终编译结束了
Image may be NSFW.
Clik here to view.
接下来要把编译出的一些动态库拷贝到caffe\build目录下,具体请参考下面的编译脚本build-install.cmd。
if not exist "%~sdp0\caffe\build\install\" ( echo do not find caffe build )else ( :: copy lib and include copy /y %~sdp0\dlfcn-win32\Release\dl.dll %~sdp0\caffe\build\install\bin copy /y %~sdp0\isaac\build\lib\Release\isaac.dll %~sdp0\caffe\build\install\bin copy /y %~sdp0\dlfcn-win32\Release\dl.dll %~sdp0\caffe\build\install\python\caffe copy /y %~sdp0\isaac\build\lib\Release\isaac.dll %~sdp0\caffe\build\install\python\caffe copy /y %~sdp0\dlfcn-win32\Release\dl.dll %~sdp0\caffe\build\tools\Release copy /y %~sdp0\isaac\build\lib\Release\isaac.dll %~sdp0\caffe\build\tools\Release copy /y %~sdp0\caffe\build\libraries\lib\boost_python-vc140-mt-1_61.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\lib\boost_system-vc140-mt-1_61.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\lib\boost_thread-vc140-mt-1_61.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\lib\boost_filesystem-vc140-mt-1_61.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\lib\boost_regex-vc140-mt-1_61.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\lib\boost_chrono-vc140-mt-1_61.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\lib\boost_date_time-vc140-mt-1_61.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\lib\boost_atomic-vc140-mt-1_61.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\lib\glog.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\lib\gflags.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\lib\libprotobuf.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\lib\caffehdf5_hl.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\lib\caffehdf5.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\lib\caffezlib.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\lib\lmdb.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\lib\leveldb.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\lib\snappy_static.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\lib\libopenblas.dll.a %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\x64\vc14\lib\opencv_highgui310.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\x64\vc14\lib\opencv_videoio310.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\x64\vc14\lib\opencv_imgcodecs310.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\x64\vc14\lib\opencv_imgproc310.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\caffe\build\libraries\x64\vc14\lib\opencv_core310.lib %~sdp0\caffe\build\install\lib copy /y %~sdp0\isaac\build\lib\Release\isaac.lib %~sdp0\caffe\build\install\lib copy /y %OPENCL_LIBRARIES% %~sdp0\caffe\build\install\lib copy /y %PYTHON_LIBRARY% %~sdp0\caffe\build\install\lib xcopy %~sdp0\caffe\build\libraries\include %~sdp0\caffe\build\install\include /s /h /c /y move /y %~sdp0\caffe\build\install\include\boost-1_61\boost %~sdp0\caffe\build\install\include\boost mkdir %~sdp0\caffe\build\install\include\viennacl xcopy %~sdp0\caffe\viennacl-dev\viennacl %~sdp0\caffe\build\install\include\viennacl /s /h /c /y mkdir %~sdp0\caffe\build\install\include\CL xcopy %~sdp0\caffe\viennacl-dev\CL %~sdp0\caffe\build\install\include\CL /s /h /c /y mkdir %~sdp0\caffe\build\install\include\3rdparty xcopy %~sdp0\caffe\include\3rdparty %~sdp0\caffe\build\install\include\3rdparty /s /h /c /y echo "copy done" )
运行
运行一下clCaffe项目自带的examples里的00-classification的代码来验证一下clCaffe是否能够正常运行,我们也可以由此看到clCaffe和BVLC caffe的运行流程上的一些不同
首先在C盘的根目录下建一个clcaffe_cache的目录,然后在这个clcaffe_cache的目录下建一个viennacl的子目录。
Image may be NSFW.
Clik here to view.
同时在Windows*的环境变量里加入VIENNACL_CACHE_PATH = c:\clcaffe_cache\viennacl
Image may be NSFW.
Clik here to view.
接下来看看电脑上的可使用的GPU设备的ID号,等下运行caffe的时候需要告诉caffe用哪个GPU设备。
打开Windows* 命令行控制台应用(command console),进入clcaffe-windows\caffe\build\tools\Release目录,执行
C:\work\clcaffe-windows\caffe\build\tools\Release>caffe.exe device_query
看一下输出,
Image may be NSFW.
Clik here to view.![]()
可以看到我的电脑上有2个GPU设备,
Device id:0 是Intel HD Graphics 630核显
Device id:1 是CPU模拟的GPU设备
接着针对00-classification用的caffe模型,我们先生成一下caffe运行这个model所需要cache文件。(如果事先不生产cache文件,这个cache也会在caffe第一次运行caffe model的时候自动生成,但是会导致程序第一次运行时的运行时间过长)
打开Windows* 命令行控制台应用(command console),进入clcaffe-windows\caffe\build\tools\Release目录,执行
C:\work\clcaffe-windows\caffe\build\tools\Release>caffe.exe time -gpu 0 -phase TEST --model ..\..\..\models\bvlc_reference_caffenet\deploy.prototxt
- 这个models\bvlc_reference_caffenet\deploy.prototxt就是用到的模型文件
Image may be NSFW.
Clik here to view.
Caffe会基于这个models来评估一个运行这个模型最快的opencl算法,并且把评估结果写到Cache文件里去。
准备工作终于结束了,下面跑一下00-classification例子吧
打开anaconda的命令行,进入clcaffe\caffe的examples目录,运行jupyter notebook
Image may be NSFW.
Clik here to view.
在打开的notebook中打开caffe自带的例子 00-calssification.ipynb
Image may be NSFW.
Clik here to view.
这是用一个训练好的Caffe模型来预测动物图片的例子,图片默认是使用Caffe项目里examples\image\cat.jpg。
先修改第2步中caffe的路径,将路径指向clcaffe
Image may be NSFW.
Clik here to view.
再修改第4步中的caffe运行模式,注释掉set_mode_cpu(),加上set_device(0),set_mode_gpu(),caffe接下来会把模型放到device id为0的GPU设备上。根据前面的caffe device_query的输出,id 0为本机的核显。
Image may be NSFW.
Clik here to view.
一路Shift+Enter运行下去,看到第8步predicted输出
predicted class is: 281
第9步输出
output label: n02123045 tabby, tabby cat
预测结果是猫,说明clcaffe已经正确编译而且能运行了。
大功告成。
使用clCaffe的一些注意事项
- clCaffe只支持Gen9及以上的Intel核显,即Intel Skylake架构及以后的微处理器的核显。
- 生成caffe cache时建议预先用无权重系数模型来生产cache,不要在caffe第一次运行你自己的代码时on-the-fly的生成cache,容易造成GPU运行出错。(这个bug正在修复中)
- Clcaffe在创建基于GPU的net模型时,这个net会基于set_device([GPU Device ID])传进去的那个GPU device ID创建。所以接下来这个net模型无法通过set_device()来切换另一个GPU硬件,如果想切换到另一个GPU上运行,必须通过set_device([GPU Device ID])设定一个新GPU Device,再重新定义一个新Net模型。
Image may be NSFW.
Clik here to view.
- Windows*下clCaffe对python支持不好,python程序在退出时会异常。在Linux下无此问题。所以建议正式代码用C++来调用caffe,同时C++接口可以定义fp16的caffe模型,获得更高的性能。
Intel clCaffe核显带来的性能提升
接下来在我的两台PC机上分别运行一下基于CPU的BVLC caffe和基于GPU加速的clCaffe,看看在日常的学习生产硬件平台上(台式机和笔记本)运行caffe,核显加速能带来多少性能的提升。测试方法为在默认的Windows*10系统且安装了常用的办公软件及开发软件的环境下(不关闭任何默认打开的后台服务),利用前面用到的caffe自带的例子 00-classification,在代码的第11步,测试net.forward()的运行时间(如下图所示)。我们基于这个测试时间来做一个简单的性能对比。
Image may be NSFW.
Clik here to view.
基于Intel Core i5-7440HQ移动处理器的性能测试
CPU信息
Image may be NSFW.
Clik here to view.
CPU版本net.forward()运行时间
Image may be NSFW.
Clik here to view.
GPU信息
Image may be NSFW.
Clik here to view.
GPU版本net.forward()运行时间
Image may be NSFW.
Clik here to view.
性能提升
1560ms/309ms = 5.05倍
基于Intel Core i7-6700 桌面处理器的性能测试
CPU信息
Image may be NSFW.
Clik here to view.
CPU版本net.forward()运行时间
Image may be NSFW.
Clik here to view.
GPU信息
Image may be NSFW.
Clik here to view.
GPU版本net.forward()运行时间
Image may be NSFW.
Clik here to view.
性能提升
1370ms/262ms = 5.23倍
两个测试平台数据对比分析
- 在Caffe的CPU实现上,Caffe模型的预测时间取决于CPU的核心数量和主频率
net.forward()时间对比
1560ms/1370ms = 1.14倍
CPU频率对比
3.4GHz/2.8GHz=1.21倍 - 在Caffe的GPU实现上,Caffe模型的预测时间主要取决于Net模型的复杂度和GPU的主频。
net.forward()时间对比
309ms/262ms = 1.18倍
GPU频率对比
1.15GHz/1GHz=1.15倍 - 相同硬件平台上CPU实现和GPU实现对比,GPU版本的处理速度领先于CPU版本5倍以上
net.forward()时间对比
平台1:1560ms/309ms = 5.05倍
平台2:1370ms/262ms = 5.23倍
结论
在人工智能领域,利用Intel核显GPU做硬件加速,在Caffe上做图像预测(Inference)时可以带来比纯CPU版本Caffe高达5倍以上的性能提升。这种使用场景特别适合使用Intel的低端桌面处理器,移动处理器,以及凌动处理器平台的IOT设备、Edge设备及家庭电脑上,在这种低功耗、低CPU性能的情况下可以利用Intel集成GPU大大提高这些硬件平台的AI预测速度。
后记
本文介绍的clCaffe并没有获得其最佳性能。要想让clCaffe获得最佳性能,我们还需要对模型进行优化(clCaffe采用的是模型融合),并采用FP16来进行推理。
模型融合(Model Fusion)意思是说在神经网络内,一些层可以合并在一起计算。通常情况下,我们可以将BatchNorm,Scale,Relu层合并进入Conv层。模型融合的好处是降低了数据读取的次数,因为在推理过程中除了运算,数据读写也占用了大量的时间。
FP16也称之为半精度浮点,一般浮点数为4字节(FP32),FP16顾名思义为2字节,大部分现代GPU中设计了FP16的运算单元, 相对FP32可以获得1.3~2倍数的性能提升。在clCaffe中可以创建Half类型的网络, 当这样的网络加载FP32的模型时,内部会自动转换成FP16的模型进行计算,速度可以进一步提升(但是,目前只能使用c/c++代码才能创建FP16网络)。
有关clCaffe的模型融合以及FP16推理相关的内容,将会在下一篇博文介绍。你也可以在这里https://github.com/liyuming1978/caffe_example找到更多的如何更好使用clCaffe的相关信息。