1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

docker上でyolov3の環境を構築してGPUで動かす

Posted at

はじめに

できること

docker上でopencv・GPUを使用してdarknet/yolov3を動かせるようになる。

本記事の流れ

以下の流れでdokcer container上でyoloV3が動く環境を作り動かしていきます。

  • opencvのインストールとbuild
  • darknetのインストールと重みのダウウンロード
  • 実行

ホスト環境

前提としてdockerが使える環境であることを想定しています。

  • windows Pro11
  • Docker Compose version v2.20.2-desktop.1
  • GPU: RTX3070
  • nvidia-driver: 536.19

コンテナの環境

  • OS: ubuntu20.04
  • cuda:11.2.0
  • cudnn: 8.0
  • OpenCV: 4.5.1
  • Python3.8

ディレクトリ構造

yolov3
├── Dockerfile
├── docker-compose.yml
└── workspace
    └── darknet
        ├── Makefile
        ├── cfg
        ├── darknet
        ├── darknet.py
        ├── darknet_images.py
        ├── darknet_video.py
        ├── data
        ├── json_mjpeg_streams.sh
        ├── predictions.jpg
        └── yolov3.weights

docker環境の構築

コンテナの起動

docker-compose.ymlDockerfileは以下のようになります。

Dockerfile
FROM nvcr.io/nvidia/cuda:11.2.0-cudnn8-devel-ubuntu20.04

ENV DEBIAN_FRONTEND=noninteractive

ARG OPENCV_VERSION="4.5.1"
ARG PYTHON_VERSION="3.8"

# cudaのレポジトリーのキーが変更されたので既存の情報を削除
RUN rm /etc/apt/sources.list.d/cuda.list

# 必要ツール
RUN apt-get update && apt-get -y upgrade &&\
    apt-get install -y --no-install-recommends \
    vim unzip byobu wget tree git cmake\
    && rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*

# pythonのインストール
RUN apt-get update && apt-get install -y python3-dev python3-pip &&\
    rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*
RUN pip3 install -U pip
RUN pip3 install -U numpy

# OpenCVのためのツール
RUN apt-get update && apt-get install -y --no-install-recommends \
    gcc g++ libpng-dev libjpeg-dev libopenexr-dev libtiff-dev libwebp-dev libgtk-3-dev \
    libavformat-dev libswscale-dev libhdf5-serial-dev qt5-default \
    libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libopenblas-dev libgflags-dev &&\
    rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*


# OpenCVのインストール
RUN mkdir /cv
WORKDIR /cv

RUN git clone https://github.com/opencv/opencv.git
RUN git clone https://github.com/opencv/opencv_contrib.git
WORKDIR /cv/opencv_contrib
RUN git checkout -b ${OPENCV_VERSION} refs/tags/${OPENCV_VERSION}
WORKDIR /cv/opencv
RUN git checkout -b ${OPENCV_VERSION} refs/tags/${OPENCV_VERSION}


WORKDIR /cv/opencv/build

# OpenCVのインストール
RUN cmake -D CMAKE_BUILD_TYPE=RELEASE \
        -D CMAKE_INSTALL_PREFIX=/usr/local \
        -D PYTHON3_PACKAGES_PATH=/usr/local/lib/python3.8/dist-packages \
        -D WITH_TBB=ON \
        -D ENABLE_FAST_MATH=1 \
        -D CUDA_FAST_MATH=1 \
        -D WITH_CUBLAS=1 \
        -D WITH_CUDA=ON \
        -D WITH_CUDNN=ON \
        -D BUILD_opencv_cudacodec=OFF \
        -D OPENCV_DNN_CUDA=ON \
        -D CUDA_ARCH_BIN="7.5, 8.0" \
        -D WITH_V4L=ON \
        -D WITH_QT=ON \
        -D WITH_OPENGL=ON \
        -D WITH_GSTREAMER=ON \
        -D OPENCV_GENERATE_PKGCONFIG=ON \
        -D OPENCV_ENABLE_NONFREE=ON \
        -D OPENCV_EXTRA_MODULES_PATH=/cv/opencv_contrib/modules\
        -D INSTALL_PYTHON_EXAMPLES=OFF \
        -D INSTALL_C_EXAMPLES=OFF \
        -D BUILD_opencv_python2=OFF \
        -D BUILD_opencv_python3=ON \
        -D PYTHON3_EXECUTABLE=/usr/bin/python3\
        -D PYTHON3_INCLUDE_DIR=/usr/include/python3.8\
        -D PYTHON3_LIBRARY=/usr/lib/libpython3.8.so\
        -D PYTHON3_NUMPY_INCLUDE_DIRS=/usr/local/lib/python3.8/dist-packages/numpy/core/include\
        -D BUILD_EXAMPLES=OFF .. &&\
    make -j10 && make install && ldconfig


このDockerfileではnvidiaのレポジトリからnvidia-driverが入ったレポジトリを取得します。
そして、その上にOpenCVとPythonの環境を構築しています。

OpemCVのインストールではcudaを使ってGPUが使えるようにしてあります。
またopencv_contribのインストールやpythonでOpenCVが使えるように設定してあります。

docker-compose.yml

version: "3.2"
services:
  ubuntu:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: "y3"
    volumes:
      - /dev/bus/usb:/dev/bus/usb
      - ./workspace:/workspace
    deploy:
      resources:
        reservations:
          devices:
            - capabilities: [gpu]
    environment:
      - NVIDIA_VISIBLE_DEVICES=all
      - NVIDIA_DRIVER_CAPABILITIES=all
    tty: true

docker-compose.ymlではコンテナ上でGPUが使えるようにセッティングしてあります。
またコードの書き換えがしやすいようにworkspaceをマウントしています。
コンテナ名はy3としていますのでお好きな名前に変更していただいて結構です。

yolov3/以下で

docker compose build 
docker compose  up 
docker exec -it y3 bash

を行いコンテナの中に入れるか確認します。
※ビルドには結構時間がかかります。

OpenCVの確認

コンテナ内でopencvが使えるか確認します。

opencv_version
4.5.1

pythonから見えるか確認

python3
Python 3.8.10 (default, May 26 2023, 14:05:08)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> cv2.__version__
'4.5.1'

darknetのインストール

コンテナ外のworkspace以下にgitファイルをクローン

git clone git@github.com:AlexeyAB/darknet.git

darknetディレクトリに入り、その中のMakefileを編集します。

GPU=1
CUDNN=1
CUDNN_HALF=0
OPENCV=1
AVX=0
OPENMP=0
LIBSO=1
ZED_CAMERA=0
ZED_CAMERA_v2_8=0

# set GPU=1 and CUDNN=1 to speedup on GPU
# set CUDNN_HALF=1 to further speedup 3 x times (Mixed-precision on Tensor Cores) GPU: Volta, Xavier, Turing, Ampere, Ada and higher
# set AVX=1 and OPENMP=1 to speedup on CPU (if error occurs then set AVX=0)
# set ZED_CAMERA=1 to enable ZED SDK 3.0 and above
# set ZED_CAMERA_v2_8=1 to enable ZED SDK 2.X

USE_CPP=0
DEBUG=0

ARCH= -gencode arch=compute_50,code=[sm_50,compute_50] \
      -gencode arch=compute_52,code=[sm_52,compute_52] \
	    -gencode arch=compute_61,code=[sm_61,compute_61]

OS := $(shell uname)

# Naming confusion with recent RTX cards.
# "NVIDIA Quadro RTX x000" and T1000/Tx00 are Turing Architecture Family with Compute Capability of 7.5
# "NVIDIA RTX Ax000" are Ampere Architecture Family with Compute Capability of 8.6
# NVIDIA "RTX x000 Ada" are Ada Lovelace Architecture Family with Compute Capability of 8.9
# Source https://developer.nvidia.com/cuda-gpus

# KEPLER, GeForce GTX 770, GTX 760, GT 740
# ARCH= -gencode arch=compute_30,code=sm_30

# MAXWELL, GeForce GTX 950, 960, 970, 980, 980 Ti, "GTX" Titan X
# ARCH= -gencode arch=compute_52,code=sm_52

# Jetson TX1, Tegra X1, DRIVE CX, DRIVE PX, Jetson Nano (2GB, 4GB)
# ARCH= -gencode arch=compute_53,code=[sm_53,compute_53]

# GP100/Tesla P100 - DGX-1
# ARCH= -gencode arch=compute_60,code=sm_60

# PASCAL, GTX 10x0, GTX 10x0 Ti, Titan Xp, Tesla P40, Tesla P4
# ARCH= -gencode arch=compute_61,code=[sm_61,compute_61]

# For Jetson TX2, Jetson Nano TX2 or Drive-PX2 uncomment:
# ARCH= -gencode arch=compute_62,code=[sm_62,compute_62]

# Tesla V100
# ARCH= -gencode arch=compute_70,code=[sm_70,compute_70]

# Jetson XAVIER, XAVIER NX
# ARCH= -gencode arch=compute_72,code=[sm_72,compute_72]

# GeForce Titan RTX, RTX 20x0, RTX 20x0 Ti, Quadro RTX x000, Tesla T4, XNOR Tensor Cores
# ARCH= -gencode arch=compute_75,code=[sm_75,compute_75]

# Tesla A100 (GA100), DGX-A100, A30, A100, RTX 3080
# ARCH= -gencode arch=compute_80,code=[sm_80,compute_80]

# GeForce RTX 30x0, 30x0 Ti, Tesla GA10x, RTX Axxxx, A2, A10, A16, A40
ARCH= -gencode arch=compute_86,code=[sm_86,compute_86]

# NOT TESTED, THEORETICAL
# Jetson ORIN, ORIN NX, ORIN NANO
# ARCH= -gencode arch=compute_87,code=[sm_87,compute_87]

# NOT TESTED, THEORETICAL
# GeForce RTX 4070 Ti, 4080, 4090, L4, L40
# ARCH= -gencode arch=compute_89,code=[sm_89,compute_89]

# NOT TESTED, THEORETICAL
# Nvidia H100
# ARCH= -gencode arch=compute_90,code=[sm_90,compute_90]

VPATH=./src/
EXEC=darknet
OBJDIR=./obj/

ifeq ($(LIBSO), 1)
LIBNAMESO=libdarknet.so
APPNAMESO=uselib
endif

ifeq ($(USE_CPP), 1)
CC=g++
else
CC=gcc
endif

CPP=g++ -std=c++11
NVCC=nvcc
OPTS=-Ofast
LDFLAGS= -lm -pthread
COMMON= -Iinclude/ -I3rdparty/stb/include
CFLAGS=-Wall -Wfatal-errors -Wno-unused-result -Wno-unknown-pragmas -fPIC -rdynamic

ifeq ($(DEBUG), 1)
#OPTS= -O0 -g
#OPTS= -Og -g
COMMON+= -DDEBUG
CFLAGS+= -DDEBUG
else
ifeq ($(AVX), 1)
CFLAGS+= -ffp-contract=fast -mavx -mavx2 -msse3 -msse4.1 -msse4.2 -msse4a
endif
endif

CFLAGS+=$(OPTS)

ifneq (,$(findstring MSYS_NT,$(OS)))
LDFLAGS+=-lws2_32
endif

ifeq ($(OPENCV), 1)
COMMON+= -DOPENCV
CFLAGS+= -DOPENCV
LDFLAGS+= `pkg-config --libs opencv4 2> /dev/null || pkg-config --libs opencv`
COMMON+= `pkg-config --cflags opencv4 2> /dev/null || pkg-config --cflags opencv`
endif

ifeq ($(OPENMP), 1)
    ifeq ($(OS),Darwin) #MAC
	    CFLAGS+= -Xpreprocessor -fopenmp
	else
		CFLAGS+= -fopenmp
	endif
LDFLAGS+= -lgomp
endif

ifeq ($(GPU), 1)
COMMON+= -DGPU -I/usr/local/cuda/include/
CFLAGS+= -DGPU
ifeq ($(OS),Darwin) #MAC
LDFLAGS+= -L/usr/local/cuda/lib -lcuda -lcudart -lcublas -lcurand
else
LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand
endif
endif

ifeq ($(CUDNN), 1)
COMMON+= -DCUDNN
ifeq ($(OS),Darwin) #MAC
CFLAGS+= -DCUDNN -I/usr/local/cuda/include
LDFLAGS+= -L/usr/local/cuda/lib -lcudnn
else
CFLAGS+= -DCUDNN -I/usr/local/cudnn/include
LDFLAGS+= -L/usr/local/cudnn/lib64 -lcudnn
endif
endif

ifeq ($(CUDNN_HALF), 1)
COMMON+= -DCUDNN_HALF
CFLAGS+= -DCUDNN_HALF
ARCH+= -gencode arch=compute_70,code=[sm_70,compute_70]
endif

ifeq ($(ZED_CAMERA), 1)
CFLAGS+= -DZED_STEREO -I/usr/local/zed/include
ifeq ($(ZED_CAMERA_v2_8), 1)
LDFLAGS+= -L/usr/local/zed/lib -lsl_core -lsl_input -lsl_zed
#-lstdc++ -D_GLIBCXX_USE_CXX11_ABI=0
else
LDFLAGS+= -L/usr/local/zed/lib -lsl_zed
#-lstdc++ -D_GLIBCXX_USE_CXX11_ABI=0
endif
endif

OBJ=image_opencv.o http_stream.o gemm.o utils.o dark_cuda.o convolutional_layer.o list.o image.o activations.o im2col.o col2im.o blas.o crop_layer.o dropout_layer.o maxpool_layer.o softmax_layer.o data.o matrix.o network.o connected_layer.o cost_layer.o parser.o option_list.o darknet.o detection_layer.o captcha.o route_layer.o writing.o box.o nightmare.o normalization_layer.o avgpool_layer.o coco.o dice.o yolo.o detector.o layer.o compare.o classifier.o local_layer.o swag.o shortcut_layer.o representation_layer.o activation_layer.o rnn_layer.o gru_layer.o rnn.o rnn_vid.o crnn_layer.o demo.o tag.o cifar.o go.o batchnorm_layer.o art.o region_layer.o reorg_layer.o reorg_old_layer.o super.o voxel.o tree.o yolo_layer.o gaussian_yolo_layer.o upsample_layer.o lstm_layer.o conv_lstm_layer.o scale_channels_layer.o sam_layer.o
ifeq ($(GPU), 1)
LDFLAGS+= -lstdc++
OBJ+=convolutional_kernels.o activation_kernels.o im2col_kernels.o col2im_kernels.o blas_kernels.o crop_layer_kernels.o dropout_layer_kernels.o maxpool_layer_kernels.o network_kernels.o avgpool_layer_kernels.o
endif

OBJS = $(addprefix $(OBJDIR), $(OBJ))
DEPS = $(wildcard src/*.h) Makefile include/darknet.h

all: $(OBJDIR) backup results setchmod $(EXEC) $(LIBNAMESO) $(APPNAMESO)

ifeq ($(LIBSO), 1)
CFLAGS+= -fPIC

$(LIBNAMESO): $(OBJDIR) $(OBJS) include/yolo_v2_class.hpp src/yolo_v2_class.cpp
	$(CPP) -shared -std=c++11 -fvisibility=hidden -DLIB_EXPORTS $(COMMON) $(CFLAGS) $(OBJS) src/yolo_v2_class.cpp -o $@ $(LDFLAGS)

$(APPNAMESO): $(LIBNAMESO) include/yolo_v2_class.hpp src/yolo_console_dll.cpp
	$(CPP) -std=c++11 $(COMMON) $(CFLAGS) -o $@ src/yolo_console_dll.cpp $(LDFLAGS) -L ./ -l:$(LIBNAMESO)
endif

$(EXEC): $(OBJS)
	$(CPP) -std=c++11 $(COMMON) $(CFLAGS) $^ -o $@ $(LDFLAGS)

$(OBJDIR)%.o: %.c $(DEPS)
	$(CC) $(COMMON) $(CFLAGS) -c $< -o $@

$(OBJDIR)%.o: %.cpp $(DEPS)
	$(CPP) -std=c++11 $(COMMON) $(CFLAGS) -c $< -o $@

$(OBJDIR)%.o: %.cu $(DEPS)
	$(NVCC) $(ARCH) $(COMMON) --compiler-options "$(CFLAGS)" -c $< -o $@

$(OBJDIR):
	mkdir -p $(OBJDIR)
backup:
	mkdir -p backup
results:
	mkdir -p results
setchmod:
	chmod +x *.sh

.PHONY: clean

clean:
	rm -rf $(OBJS) $(EXEC) $(LIBNAMESO) $(APPNAMESO)

GPU=1
CUDNN=1
OPENCV=1
LIBSO=1
をそれぞれ1にして使えるようにします。

また、ARCH= のところのコメントアウトを外します。
このPCはGTX3070なので
# GeForce RTX 30x0, 30x0 Ti, Tesla GA10x, RTX Axxxx, A2, A10, A16, A40
のところのコメントアウトを外しました。

そのあとコンテナ内に入りdarknet/で下のコマンドを実行します。

make

YoloV3の実行

以下はコンテナ内で実行します。

初めに重みをダウンロードします。
今回はYoloV3なので以下のコマンドでV3用の重みをdarknet/にダウンロードします。

wget https://pjreddie.com/media/files/yolov3.weights

証明書エラーが出たときは--no-check-certificateをつけて回避します。

続いて以下のコマンドでYoloV3を実行します。

./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg

実行するとpredictions.jpgに結果が出力されますので
image.png
こんな感じの写真が出ればOKです。
darknet/data/には他にもデモ写真が含まれています。

image.pngimage.png

pythonで実行する場合は

python3 darknet_images.py --input data/giraffe.jpg --weights yolov3.weights  --dont_show --config_file cfg/yolov3.cfg  --data_file cfg/coco.data 
watch -n 0.1 nvidia-smi

で動作を見てるとちゃんとGPUが動いているのがわかります。

'''

参考文献

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?