本文主要参考:
(1)
Ubuntu18下编译安装torchvision—C++API的详细过程_Flag_ing的博客-CSDN博客_编译torchvision
(2)libtorch和torchvision的编译安装_陈建驱的博客-CSDN博客_torchvision编译
(3)Win10编译安装libtorch+torchvision_白刃的阿白的博客-CSDN博客_win10编译libtorch
最近使用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命令行输入下面指令即可,注意路径。
git clone https://github.com/pybind/pybind11.git
cd pybind11
mkdir build
cd build
cmake -DPYBIND11_TEST=OFF -DCMAKE_INSTALL_PREFIX="\where\to\install\pybind11" ..
cmake --install .
cmake报错的话!看这个: 因为c++编译器它是默认使用的VS的32位编译器,如果使用的python是64位的就会报错。 解决方式就把cmake那一句替换为下面指令,然后再install。(其实就是指定一下64位的编译器。至于具体是哪个VS版本,要根据自己的安装的版本进行替换,这个报错信息里面有提示)
(5)安装libjpeg和zlib
接下来使用conda的命令行在环境中安装两个包:
conda install -c conda-forge libjpeg-turbo
conda install -c anaconda zlib
这步是因为torchvision的CMakeLists.txt中有这么几行:
find_package(Python3 COMPONENTS Development)
find_package(Torch REQUIRED)
find_package(PNG REQUIRED)
find_package(JPEG REQUIRED)
意思是除了libtorch,PNG和JPEG也是这里需要的。不安装这俩东西的话后面会报错。
(6)build torchvision
cmake -DCMAKE_PREFIX_PATH="D:\programfile\libtorch;C:\where\to\install\pybind11" .. -DCMAKE_INSTALL_PREFIX="D:\programfile\torchvision_0100\torchvision" -DCMAKE_BUILD_TYPE=Release -DWITH_CUDA=ON ..
注意:因为我要安装的是GPU版本的,想要装CPU版本的话可以在命令行紧跟在Release后面中不加入 -DWITH_CUDA=ON 参数
完成后build文件夹应该会生成这些东西:
(7)cmake工程建立后的vs编译安装
我这里就在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:
cmake_minimum_required(VERSION 3.10)
project(hello-world)
# The first thing do is to tell cmake to find the TorchVision library.
# The package pulls in all the necessary torch libraries,
# so there is no need to also add `find_package(Torch)` here.
find_package(TorchVision REQUIRED)
add_executable(hello-world main.cpp)
# We now need to link the TorchVision library to our executable.
# We can do that by using the TorchVision::TorchVision target,
# which also adds all the necessary torch dependencies.
target_compile_features(hello-world PUBLIC cxx_range_for)
target_link_libraries(hello-world TorchVision::TorchVision)
set_property(TARGET hello-world PROPERTY CXX_STANDARD 14)
main.cpp:
#include
#include
#include
#include
int main()
{
auto model = vision::models::ResNet18();
model->eval();
// Create a random input tensor and run it through the model.
auto in = torch::rand({1, 3, 10, 10});
auto out = model->forward(in);
std::cout << out.sizes();
if (torch::cuda::is_available()) {
// Move model and inputs to GPU
model->to(torch::kCUDA);
auto gpu_in = in.to(torch::kCUDA);
auto gpu_out = model->forward(gpu_in);
std::cout << gpu_out.sizes();
}
}
README.rst:
Hello World!
============
This is a minimal example of getting TorchVision to work in C++ with CMake.
In order to successfully compile this example, make sure you have both ``LibTorch`` and
``TorchVision`` installed.
Once both dependencies are sorted, we can start the CMake fun:
1) Create a ``build`` directory inside the current one.
2) from within the ``build`` directory, run the following commands:
- | ``cmake -DCMAKE_PREFIX_PATH=";" ..``
| where ```` and ```` are the paths to the libtorch and torchvision installations.
- ``cmake --build .``
| That's it!
| You should now have a ``hello-world`` executable in your ``build`` folder.
Running it will output a (fairly long) tensor of random values to your terminal.
这个测试例子,我最后没有使用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应该放到库目录中了。
而且我这一次编译完获取的这个文件,可以移植到其他任何机器上了。