一个基于Docker的TensorRT+OpenCV项目的环境配置

一个基于Docker的TensorRT+OpenCV项目的环境配置,第1张

最近做了个基于docker的深度学习项目,这里简要记录一下整个环境的搭建和遇到的坑,供自己以后回看和大家借鉴。


环境依赖

python 3.7.13
cuda10.2 cudnn 8.0.4
TensorRT 7.2.1.6
OpenCV 3.4.16

docker相关

由于环境依赖过于复杂,使用dockerfile直接进行部署不太现实,这里使用的是基于nvidia/cuda:10.2-cudnn8-devel-ubuntu18.04镜像进行改动,初始的dockerfile文件如下。


FROM nvidia/cuda:10.2-cudnn8-devel-ubuntu18.04

# 更新apt源
COPY sources.list /etc/apt/

# 设置入点
ENTRYPOINT ["bin/bash"]

nvidia镜像中已经安装好了cuda10.2,由于apt默认使用的国外的源进行下载和更新,这里使用了阿里云的源进行替换,只替换了前四个。


# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
# newer versions of the distribution.
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted
# deb-src http://archive.ubuntu.com/ubuntu/ bionic main restricted

## Major bug fix updates produced after the final release of the
## distribution.
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted
# deb-src http://archive.ubuntu.com/ubuntu/ bionic-updates main restricted

## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team. Also, please note that software in universe WILL NOT receive any
## review or updates from the Ubuntu security team.
deb http://mirrors.aliyun.com/ubuntu/ bionic universe
# deb-src http://archive.ubuntu.com/ubuntu/ bionic universe
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates universe
# deb-src http://archive.ubuntu.com/ubuntu/ bionic-updates universe
cmake安装

此时docker内是没有cmake的,因此需要先完成cmake的安装,去官网https://cmake.org/download/选择版本,下载最新版就行了,以cmake-3.23.0为例,将压缩包cmake-3.23.0.tar.gz放入容器中,解压,然后

./bootstrap
make
make install

使用cmake --version进行测试

有类似输出就表示安装成功

python相关

创建容器,首先使用apt-get update进行更新,然后安装python的依赖项。


apt-get update
apt-get -y install build-essential python-dev python-setuptools python-pip python-smbus libncursesw5-dev libgdbm-dev libc6-dev zlib1g-dev libsqlite3-dev tk-dev libssl-dev openssl libffi-dev

说实话我也不知道为啥要安装这么多的依赖项,也许有的可以不装,但我懒得试了。


然后选择你要安装的python版本,在https://www.python.org/downloads/里找到对应的压缩包,以我用的python3.7.13为例,最后下载得到了Python-3.7.13.tar.xz。



将压缩包传入docker容器中,解压,并进行安装。


mkdir -p /usr/local/python3.7
# 我将Python-3.7.13.tar.xz放入了/tmp文件夹中
cd /tmp && tar xvf Python-3.7.13.tar.xz
cd Python-3.7.13
# 这里的prefix是输入你最后想要放置python的位置
./configure --prefix=/usr/local/python3.7
# 可以使用make -j7 来加速make过程,-jn表示使用n个线程进行make
make && make install
# 将刚才生成的程序python3.7链接为python3,这样输入python3指令就代表了python3.7
ln -snf /usr/local/python3.7/bin/python3.7 /usr/bin/python3
# 输入python指令表示python3.7
ln -snf /usr/local/python3.7/bin/python3.7 /usr/bin/python
# pip
ln -snf /usr/local/python3.7/bin/pip3.7 /usr/bin/pip3
ln -snf /usr/local/python3.7/bin/pip3.7 /usr/bin/pip
# 清空缓存
apt-get clean

执行完上述指令后,可以使用python进行测试

这样python就安装成功了

TensorRT安装

我将TensorRT的安装和cudnn放在一起说,因为他们俩的版本号是对应的,首先去官网https://developer.nvidia.com/nvidia-tensorrt-download查看列表,官网是需要登录的,没有账号的需要先注册一个。



当你确定了一个TensorRT版本时(如我选取的TensorRT-7.2.1.6),点击对应的TensorRT X,根据你的CUDA版本和Linux版本,cudnn版本也就确定了。




下载得到了TensorRT-7.2.1.6.Ubuntu-18.04.x86_64-gnu.cuda-10.2.cudnn8.0.tar.gz文件。



然后去cudnn官网https://developer.nvidia.com/cudnn,找到对应的cudnn。




下载第一个就可以,得到了cudnn-10.2-linux-x64-v8.0.4.30.tgz文件。


接下来要开始TensorRT的安装了

# 同样 cudnn和TensorRT的安装包都在/tmp文件夹中
cd /tmp
tar xvf cudnn-10.2-linux-x64-v8.0.4.30.tgz
# 解压得到了cuda文件夹,将其放到cuda所在文件夹,并改名为cudnn
mv cuda /usr/local/cuda-10.2/cudnn
# 如果想要永久生效需要把这个指令放在~/.bashrc里 并使用source ~/.bashrc
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda-10.2/cudnn/lib64
tar xvf TensorRT-7.2.1.6.Ubuntu-18.04.x86_64-gnu.cuda-10.2.cudnn8.0.tar.gz
# 将TensorRT文件夹放到你想放置的位置,我这里是放到了/usr/local/下
mv TensorRT-7.2.1.6 /usr/local/TensorRT-7.2.1.6
# 如果你需要在python中使用TensorRT,建议看官方的教程https://docs.nvidia.com/deeplearning/tensorrt/install-guide/index.html#installing-tar 
# 查看教程4.6节,并进行相应的测试

这样就完成了TensorRT的安装。


OpenCV安装

OpenCV安装真的是巨坑,这里我选择了OpenCV3.4.16版本,首先你需要确定你编写的程序需要使用的到库,当然你也可以先编译普通的版本进行测试,如果程序无法运行或者make出错再考虑是不是哪里有问题。



首先从官网下载OpenCV,得到3.4.16.tar.gz压缩包。


cd /tmp
tar xvf 3.4.16.tar.gz
cd opencv-3.4.16
mkdir build && cd build

这里重点说一下cmake指令,你想要生成一个什么样的opencv都取决于你cmake时输入的参数,关于所有参数的说明可以查看opencv的CMakeLists.txt。



-DCMAKE_INSTALL_PREFIX表示你想要安装opencv的地址

# 基础的cmake指令
cmake -DCMAKE_BUILD_TYPE=RELEASE \
	  -DCMAKE_INSTALL_PREFIX=/usr/local \
	  ..

如果你需要使用cuda加速,那么需要在cmake中加入以下

	-DWITH_CUDA=ON \
	-DENABLE_FAST_MATH=1 \
	-DCUDA_FAST_MATH=1 \
	-DWITH_CUBLAS=1 \
	-DCUDA_GENERATION=Turing \

其中,CUDA_GENERATION=Turing需要根据你显卡的实际架构来决定,可查看https://en.wikipedia.org/wiki/CUDA#GPUs_supported来确定,我使用的是2080,所以这里的CUDA_GENERATION是Turing。



如果你需要使用一些opencv_contrib里的功能(如bgsegm啥的),需要先去git https://github.com/opencv/opencv_contrib得到opencv_contrib,然后在cmake里加入

	-DOPENCV_EXTRA_MODULES_PATH=<opencv_contrib>/modules

如果需要使用ffmpeg,首先需要确定ffmpeg的版本,因为一个opencv对应的ffmpeg版本有一个上限,在与ffmpeg相关的opencv代码中都能看到相应的限制,关于这个ffmpeg的版本的确定在opencv3里不太确定在哪,opencv2里面3rdparty/ffmpeg/文件夹下有version文件,因此建议下载一个较老版本的ffmpeg,然后在opencv的cmake中加入

	-DWITH_FFMPEG=ON

当cmake之后的输出中能看到如下图的类似输出时,就表示ffmpeg应该没有大问题了。




cmake之后就是make和make install了,安装完成后将/usr/local/opencv/lib添加进LD_LIBRARY_PATH中

测试

在完成上述所有工作后,我们可以通过一个简单的程序进行测试
CMakeLists.txt

cmake_minimum_required(VERSION 3.0)
project(install_test)

add_definitions(-std=c++11)
option(CUDA_USE_STATIC_CUDA_RUNTIME OFF)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_BUILD_TYPE Debug)

find_package(CUDA REQUIRED)
# cuda
include_directories(/usr/local/cuda-10.2/include)
link_directories(/usr/local/cuda-10.2/lib64)
# cudnn
include_directories(/usr/local/cuda-10.2/cudnn/include)
link_directories(/usr/local/cuda-10.2/cudnn/lib64)
# tensorrt
include_directories(/usr/local/TensorRT-7.2.1.6/include)
link_directories(/usr/local/TensorRT-7.2.1.6/lib)
#opencv
find_package(OpenCV)
include_directories(${OpenCV_INCLUDE_DIRS})

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Ofast -Wfatal-errors -D_MWAITXINTRIN_H_INCLUDED")

add_executable(install_test main.cpp)
target_link_libraries(install_test nvinfer)
target_link_libraries(install_test cudart)
target_link_libraries(install_test ${OpenCV_LIBS})

add_definitions(-O2 -pthread)

然后编写一下main.cpp,这里建议在github上找一个相关的项目进行测试(我不会写测试代码)
main.cpp

#include 
#include 
#include 
#include "NvInfer.h"
#include "cuda_runtime_api.h"

using namespace nvinfer1;
using namespace std;
using namespace cv;

#define DEVICE 0

int main(int argc, char** argv)
{
	Mat image;
	image = imread("img.jpg"); // 输入测试图片的地址
	VideoCapture cap("video.mp4"); // 输入测试视频的地址
	if(!cap.isOpened()) {
		cerr << "视频part有问题" << endl;
	}
	cudaSetDevice(DEVICE);
	return 0;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/567649.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-09
下一篇 2022-04-09

发表评论

登录后才能评论

评论列表(0条)

保存