Quantcast
Channel: 英特尔开发人员专区文章
Viewing all articles
Browse latest Browse all 154

Caffe学习笔记 第二部分 - Windows* 下基于Intel核显加速的clCaffe的安装,配置与性能提升

$
0
0

作者:Gu, Jianjun

点击访问Caffe学习笔记 第一部分 - Windows*下BVLC Caffe的安装与配置

clCaffe编译与配置

Intel clCaffe (https://github.com/01org/caffe)是利用基于Intel Skylake及以后的处理器核显(即Gen9架构以上)做硬件加速的一个修改版。如果你当前机器是基于Nvdia显卡,请用NV cuda加速版本;如果你的显卡是AMD的,请check out 官方BVLC caffe的opencl分支。

clCaffe的编译

安装编译所需要的软件

配置Windows*的环境变量

为了避免等会CMAKE生成编译脚本的时候找不到一些依赖关系,有的没的路径都加一些,包括Cmake, Git, Ananconda以及Python的路径。(环境变量的配置同上篇文章的2.2部分 )

下载和编译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

这个错误不是本机编译环境的问题,而是因为这个项目还不完善,在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

最终编译结束了

接下来要把编译出的一些动态库拷贝到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的子目录。

同时在Windows*的环境变量里加入VIENNACL_CACHE_PATH = c:\clcaffe_cache\viennacl

接下来看看电脑上的可使用的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

看一下输出,

可以看到我的电脑上有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就是用到的模型文件

Caffe会基于这个models来评估一个运行这个模型最快的opencl算法,并且把评估结果写到Cache文件里去。

准备工作终于结束了,下面跑一下00-classification例子吧

打开anaconda的命令行,进入clcaffe\caffe的examples目录,运行jupyter notebook

在打开的notebook中打开caffe自带的例子 00-calssification.ipynb

这是用一个训练好的Caffe模型来预测动物图片的例子,图片默认是使用Caffe项目里examples\image\cat.jpg。

先修改第2步中caffe的路径,将路径指向clcaffe

再修改第4步中的caffe运行模式,注释掉set_mode_cpu(),加上set_device(0),set_mode_gpu(),caffe接下来会把模型放到device id为0的GPU设备上。根据前面的caffe device_query的输出,id 0为本机的核显。

一路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模型。

  • 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()的运行时间(如下图所示)。我们基于这个测试时间来做一个简单的性能对比。

基于Intel Core i5-7440HQ移动处理器的性能测试

CPU信息

CPU版本net.forward()运行时间

GPU信息

GPU版本net.forward()运行时间

性能提升
1560ms/309ms = 5.05倍

基于Intel Core i7-6700 桌面处理器的性能测试

CPU信息

CPU版本net.forward()运行时间

GPU信息

GPU版本net.forward()运行时间

性能提升
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的相关信息。


Viewing all articles
Browse latest Browse all 154

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>