一、前言
最近使用libtorch做yolov5网络模型的部署,使用的是大走走的yolort,其关键部分是将后处理nms连同前面模型部分一起做了导出,使用torchvision自带的gpu版本的nms。因此在c++端用到了官方自带的nms.h等文件,但该文件需要安装torchvision,而torchvision并不包含在官方的LibTorch包中,需要自行下载源码并进行编译安装,安装过程中遇到了一些问题,在此一并记录下来。
二、编译安装步骤
1、下载torchvision源码包
GitHub - pytorch/vision: Datasets, Transforms and Models specific to Computer Vision
在这里要注意一点的是,所安装的torchvision必须要与你的LibTorch版本对应,在GitHub主页的tags中下载相应版本的torchvision,这个对应关系在官方GitHub上有说明,如下:
我自己目前使用的libtorch是1.9版本的,因此我根据pytorch类比查看,torchvision的版本是0.10.0
2、详细安装步骤
(1)解压源码包并重命名为vision(为了方便)
(2)新建torchvision文件夹
(3)在vision下新建build文件夹并进入
(4)安装pybind
需要有CMake,版本最好是新版。安装完CMake,打开cmd命令行输入下面指令即可,注意路径。
cmake报错的话!看这个: 因为c++编译器它是默认使用的VS的32位编译器,如果使用的python是64位的就会报错。 解决方式就把cmake那一句替换为下面指令,然后再install。(其实就是指定一下64位的编译器。至于具体是哪个VS版本,要根据自己的安装的版本进行替换,这个报错信息里面有提示)
(5)安装libjpeg和zlib
接下来使用conda的命令行在环境中安装两个包:
这步是因为torchvision的CMakeLists.txt中有这么几行:
意思是除了libtorch,PNG和JPEG也是这里需要的。不安装这俩东西的话后面会报错。
(6)build torchvision
注意:因为我要安装的是GPU版本的,想要装CPU版本的话可以在命令行紧跟在Release后面中不加入 -DWITH_CUDA=ON 参数
完成后build文件夹应该会生成这些东西:
(7)cmake工程建立后的vs编译安装
这一步就相当于在linux下的
我这里就在vs2019下进行编译生成:
step1:双击torchvision.sln
step2:修正编译模式并设置启动项
我们前面cmake建立工程时选择的是Release模式,因此vs编译这里也要修正为Release模式,并且设置ALL_BUILD为启动项目。右键ALL_BUILD>生成
我看了这个build完以及编译安装完的文件夹下面,大概也只有 Release 文件夹下的有用:
另外,我们想应该不止需要这个torchvision.dll和torchvision.lib。因为我发现就torchvision源码包中自带的例子而言,都是需要.h文件的:
我们来测试一下这个例子:
step3:精简编译的torchvision库以及测试代码例子
CMakeLists.txt:
main.cpp:
README.rst:
这个测试例子,我最后没有使用cmake的方式。
我最后直接自己新建解决方案,然后配置相关属性:
附加依赖项:
torchvision.lib c10.lib kineto.lib C:\Program Files\NVIDIA Corporation\NvToolsExt\\lib\x64\nvToolsExt64_1.lib cudart_static.lib caffe2_nvrtc.lib c10_cuda.lib torch.lib torch_cuda.lib torch_cuda_cu.lib D:\programfile\libtorch\lib\torch_cuda_cpp.lib torch_cpu.lib -INCLUDE:?warp_size@cuda@at@@YAHXZ cufft.lib curand.lib cublas.lib cudnn.lib -INCLUDE:?searchsorted_cuda@native@at@@YA?AVTensor@2@AEBV32@0_N1@Z kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib
运行结果如下:
最后值得注意的是:
我们已经编译完了,实际后续我们工程需要的仅仅两个文件夹:
(1)是build完以及编译安装完的文件夹下Release文件夹下的有用
(2)由于很多工程都需要包含一些torchvsion包中的.h头文件,不难想象肯定还需要一些有头文件的文件夹。如下:
我直接就把这两个文件夹拷贝走,并重新命名了:
这样就明确了哪个是include应该放到包含目录中,哪个lib应该放到库目录中了。
而且我这一次编译完获取的这个文件,可以移植到其他任何机器上了。