こちらの記事では、Jetson Nano上でPyTorchライブラリをビルドし、こちらの記事では、Jetson Nano上でOpenCVライブラリをビルドしました。これらのビルドはすべてJetson Nano上で実行しましたが、こちらの記事で解説した方法を使用しJetson Nanoのアーキテクチャであるaarch64バイナリをホストPCで実行しPyTorchとOpenCVライブラリをビルドする方法を解説します。
docker
ビルドにはDockerを使用します。Dockerを使用することでaarch64バイナリが必要とする共有ライブラリなどの環境を構築することができます。なお以下を実行し事前にログインユーザをdockerグループに追加しsudoなしでdockerコマンドを実行できるようにします。
sudo groupadd docker
sudo gpasswd -a $USER docker
Code language: PHP (php)
再起動しdockerグループへの追加を反映させます。
PyTorch
以下Dockerfileの説明です。
FROM nvcr.io/nvidia/l4t-base:r32.7.1
ENV DEBIAN_FRONTEND=noninteractive
ARG MAX_JOBS=2
Code language: Dockerfile (dockerfile)
ARG MAX_JOBS
はdocker build
時に外から--build-arg MAX_JOBS=$(nproc)
などとして渡すことを可能にしています。
# https://qengineering.eu/install-pytorch-on-jetson-nano.html
RUN apt-get update && apt-get install -y \
python3.8 python3.8-dev \
ninja-build git cmake clang \
libopenmpi-dev libomp-dev ccache \
libopenblas-dev libblas-dev libeigen3-dev \
python3-pip libjpeg-dev \
gnupg2 curl
RUN apt-key adv --fetch-key http://repo.download.nvidia.com/jetson/jetson-ota-public.asc
RUN echo 'deb https://repo.download.nvidia.com/jetson/common r32.7 main\n\
deb https://repo.download.nvidia.com/jetson/t210 r32.7 main' > /etc/apt/sources.list.d/nvidia-l4t-apt-source.list
RUN apt-get update && apt-get install -y nvidia-cuda nvidia-cudnn8
RUN python3.8 -m pip install -U pip
RUN python3.8 -m pip install -U setuptools
RUN python3.8 -m pip install -U wheel mock pillow
RUN python3.8 -m pip install scikit-build
RUN python3.8 -m pip install cython Pillow
Code language: Dockerfile (dockerfile)
途中repo.download.nvidia.com
をapt repositoryに追加し、その後nvidia-cuda nvidia-cudnn8
をインストールしています。
以降はこちらの記事で説明したものとほぼ同じになります。
## download PyTorch v1.11.0 with all its libraries
RUN git clone -b v1.11.0 --depth 1 --recursive --recurse-submodules --shallow-submodules https://github.com/pytorch/pytorch.git
WORKDIR pytorch
RUN python3.8 -m pip install -r requirements.txt
COPY pytorch-1.11-jetson.patch .
RUN patch -p1 < pytorch-1.11-jetson.patch
RUN apt-get install -y software-properties-common lsb-release
RUN wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null
RUN apt-add-repository "deb https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main"
RUN apt-get update && apt-get install -y cmake
ENV BUILD_CAFFE2_OPS=OFF
ENV USE_FBGEMM=OFF
ENV USE_FAKELOWP=OFF
ENV BUILD_TEST=OFF
ENV USE_MKLDNN=OFF
ENV USE_NNPACK=OFF
ENV USE_XNNPACK=OFF
ENV USE_QNNPACK=OFF
ENV USE_PYTORCH_QNNPACK=OFF
ENV USE_CUDA=ON
ENV USE_CUDNN=ON
ENV TORCH_CUDA_ARCH_LIST="5.3;6.2;7.2"
ENV USE_NCCL=OFF
ENV USE_SYSTEM_NCCL=OFF
ENV USE_OPENCV=OFF
ENV MAX_JOBS=$MAX_JOBS
# set path to ccache
ENV PATH=/usr/lib/ccache:$PATH
# set clang compiler
ENV CC=clang
ENV CXX=clang++
# create symlink to cublas
# ln -s /usr/lib/aarch64-linux-gnu/libcublas.so /usr/local/cuda/lib64/libcublas.so
# start the build
RUN python3.8 setup.py bdist_wheel
RUN find /pytorch/dist/ -type f|xargs python3.8 -m pip install
# torch vision
RUN git clone --depth=1 https://github.com/pytorch/vision torchvision -b v0.12.0
RUN cd torchvision && \
TORCH_CUDA_ARCH_LIST='5.3;6.2;7.2' \
FORCE_CUDA=1 \
python3.8 setup.py bdist_wheel
Code language: Dockerfile (dockerfile)
上記Dockerfileをビルドします。
docker build -t pytorch-build . --build-arg MAX_JOBS=$(nproc)
Code language: Bash (bash)
Jetson Nanoでビルドする際はメモリが少ない為MAX_JOBS=2を指定しましたが、ホストPCではこの制限は緩やかです。
ビルドが終わったら、ビルドされたバイナリを取り出します。
$ id=$(docker run -it --rm -d pytorch-build bash)
$ pytorch=$(docker exec -it ${id} find /pytorch/dist -type f | sed -e "s/[\r\n]\+//g")
$ vision=$(docker exec -it ${id} find /pytorch/torchvision/dist -type f | sed -e "s/[\r\n]\+//g")
$ docker cp ${id}:${pytorch} .
$ docker cp ${id}:${vision} .
$ docker stop ${id}
$ ls Dockerfile *whl
Dockerfile torch-1.11.0a0+gitbc2c6ed-cp38-cp38-linux_aarch64.whl torchvision-0.12.0a0+9b5a3fe-cp38-cp38-linux_aarch64.whl
Code language: Bash (bash)
手元にtorch-1.11.0a0+gitbc2c6ed-cp38-cp38-linux_aarch64.whl
とtorchvision-0.12.0a0+9b5a3fe-cp38-cp38-linux_aarch64.whl
の2つができました。
これら2つをJetson Nanoにコピーしインストールします。以下はJetson Nanoで実行します。
sudo apt update
sudo apt install -y \
python3.8 python3.8-dev python3-pip \
libopenmpi-dev libomp-dev libopenblas-dev libblas-dev libeigen3-dev \
nvidia-cuda nvidia-cudnn8
python3.8 -m pip install -U pip
python3.8 -m pip install torch-*.whl torchvision-*.whl
Code language: Bash (bash)
OpenCV
以下Dockerfileの説明です。
FROM nvcr.io/nvidia/l4t-base:r32.6.1
ENV DEBIAN_FRONTEND=noninteractive
ARG VER="4.6.0"
ARG PREFIX=/usr/local
ARG MAX_JOBS
Code language: Dockerfile (dockerfile)
こちらも、いくつかの変数をdocker build
時に--build-arg
で渡せるようにしています。以降はこちらの記事で説明したものとほぼ同じになります。
# setup
RUN cd tmp && mkdir build_opencv
WORKDIR /tmp/build_opencv
# install_dependencies
RUN apt-get update && \
apt-get install -y \
build-essential \
cmake \
git \
gfortran \
libatlas-base-dev \
libavcodec-dev \
libavformat-dev \
libavresample-dev \
libcanberra-gtk3-module \
libdc1394-22-dev \
libeigen3-dev \
libglew-dev \
libgstreamer-plugins-base1.0-dev \
libgstreamer-plugins-good1.0-dev \
libgstreamer1.0-dev \
libgtk-3-dev \
libjpeg-dev \
libjpeg8-dev \
libjpeg-turbo8-dev \
liblapack-dev \
liblapacke-dev \
libopenblas-dev \
libpng-dev \
libpostproc-dev \
libswscale-dev \
libtbb-dev \
libtbb2 \
libtesseract-dev \
libtiff-dev \
libv4l-dev \
libxine2-dev \
libxvidcore-dev \
libx264-dev \
pkg-config \
python3.8-dev \
python3.8-dev \
python3-numpy \
python3-matplotlib \
python3-pip \
qv4l2 \
v4l-utils \
v4l2ucp \
zlib1g-dev
# git_source ${VER}
RUN git clone --depth 1 --branch ${VER} https://github.com/opencv/opencv.git
RUN git clone --depth 1 --branch ${VER} https://github.com/opencv/opencv_contrib.git
RUN python3 -m pip install -U pip
RUN python3 -m pip uninstall -y numpy
RUN python3.8 -m pip install -U pip
RUN python3.8 -m pip install setuptools
RUN python3.8 -m pip install numpy
RUN apt-key adv --fetch-key http://repo.download.nvidia.com/jetson/jetson-ota-public.asc
RUN echo 'deb https://repo.download.nvidia.com/jetson/common r32.6 main\n\
deb https://repo.download.nvidia.com/jetson/t210 r32.6 main' > /etc/apt/sources.list.d/nvidia-l4t-apt-source.list
RUN apt-get update && apt-get install -y nvidia-cuda nvidia-cudnn8
RUN cd opencv && \
mkdir build && \
cd build && \
cmake \
-D BUILD_EXAMPLES=OFF \
-D BUILD_opencv_python2=OFF \
-D BUILD_opencv_python3=ON \
-D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=${PREFIX} \
-D CUDA_ARCH_BIN=5.3,6.2,7.2 \
-D CUDA_ARCH_PTX= \
-D CUDA_FAST_MATH=ON \
-D CUDNN_VERSION='8.0' \
-D EIGEN_INCLUDE_PATH=/usr/include/eigen3 \
-D ENABLE_NEON=ON \
-D OPENCV_DNN_CUDA=ON \
-D OPENCV_ENABLE_NONFREE=ON \
-D OPENCV_EXTRA_MODULES_PATH=/tmp/build_opencv/opencv_contrib/modules \
-D OPENCV_GENERATE_PKGCONFIG=ON \
-D WITH_CUBLAS=ON \
-D WITH_CUDA=ON \
-D WITH_CUDNN=ON \
-D WITH_GSTREAMER=ON \
-D WITH_LIBV4L=ON \
-D WITH_OPENGL=ON \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_TESTS=OFF \
-D PYTHON3_EXECUTABLE=python3.8 \
-D PYTHON3_INCLUDE_PATH=$(python3.8 -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())") \
-D PYTHON3_PACKAGES_PATH=$(python3.8 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())") \
-D PYTHON3_LIBRARY=/usr/lib/aarch64-linux-gnu/libpython3.8.so \
-D CPACK_BINARY_DEB=ON \
-D CPACK_PACKAGING_INSTALL_PREFIX=${PREFIX} \
..
WORKDIR /tmp/build_opencv/opencv/build
RUN make -j${MAX_JOBS}
RUN make install
RUN cpack -G DEB
Code language: Dockerfile (dockerfile)
debパッケージを作成するために、cmakeのオプションに、-D CPACK_BINARY_DEB=ON
と-D CPACK_PACKAGING_INSTALL_PREFIX=${PREFIX}
を追加しています。最後に、cpack -G DEB
でdebパッケージを作成します。
上記Dockerfileをビルドします。
docker build -t opencv-build . --build-arg MAX_JOBS=$(nproc)
Code language: Bash (bash)
ビルドが終わったら、ビルドされたバイナリを取り出します。
$ id=$(docker run -it --rm -d opencv-build bash)
$ debs=$(docker exec -it ${id} find /tmp/build_opencv/opencv/build/ -maxdepth 1 -name "*.deb" | sed -e "s/[\r\n]\+//g")
$ for deb in $debs; do
docker cp ${id}:$deb .
done
$ docker stop ${id}
$ ls Dockerfile *deb
Dockerfile OpenCV-4.6.0-aarch64-dev.deb OpenCV-4.6.0-aarch64-libs.deb OpenCV-4.6.0-aarch64-licenses.deb OpenCV-4.6.0-aarch64-main.deb OpenCV-4.6.0-aarch64-python.deb OpenCV-4.6.0-aarch64-scripts.deb
Code language: Bash (bash)
これらのdebパッケージをJetson Nanoにコピーしインストールします。以下はJetson Nanoで実行します。
sudo apt update
apt list --installed *opencv*|awk -F/ '/opencv/ {print $1}'|sudo xargs apt remove -y
sudo apt install -y ./OpenCV*.deb
Code language: Bash (bash)
既存のopencvパッケージを削除してからビルドしたOpenCVパッケージをインストールします。
パフォーマンス
PytorchのDockerビルド、OpenCVのDockerビルドをそれぞれJetson NanoとホストPC上で実行した時間を掲載します。
Jetson Nano | Host PC i9-12900K, 32GB | faster | |
PyTorch | MAX_JOBS=2 real 832m39.333s user 0m7.352s sys 0m4.268s | MAX_JOBS=24 real 176m48.354s user 0m0.852s sys 0m0.904s | x4.7 |
OpenCV | MAX_JOBS=4 real 161m34.754s user 0m2.240s sys 0m1.660s | MAX_JOBS=24 real 117m28.657s user 0m0.648s sys 0m0.517s | x1.3 |
ホストPCでのビルドはPyTorchで4.7倍、OpenCVで1.3倍、高速にビルドすることが可能です。またホストPCでのビルドは機材に依存しないためCI/CDなどのビルドサーバに導入することが可能です。
上記のコードは https://github.com/otamajakusi/build_jetson_nano_libraries にまとめてあります。
以上です。