MXNet Installation on NVIDIA Jetson Nano

Problem Statement

AWS ๊ณต์‹ ๋ฌธ์„œ์—์„œ ์„ค์น˜๋ฒ•์ด ์žˆ์ง€๋งŒ ์žฌ์ž‘๋…„ ๊ธฐ์ค€์˜ ๋‚ด์šฉ์ด๊ณ , CUDA 9.0์œผ๋กœ pre-compiled๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๊ธฐ ๋•Œ๋ฌธ์—, CUDA 10.0์ด ๊ธฐ๋ณธ์œผ๋กœ ์„ค์น˜๋œ Jetson Nano์—์„  ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ.

๋‹คํ–‰ํžˆ(?) MXNet ๊ณต์‹ ํ™ˆํŽ˜์ด์ง€์™€ NVIDIA ํฌ๋Ÿผ์—์„œ 1.4.1 ๊ธฐ์ค€์˜ ์„ค์น˜ ๋ฐฉ๋ฒ•์„ ์ œ์‹œํ•˜๊ณ  ์žˆ์ง€๋งŒ, ํ˜„ ์‹œ์ ์—์„œ๋Š” OpenCV ์˜์กด์„ฑ ์ด์Šˆ๋กœ pre-compiled ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋Œ€์‹  ์ง์ ‘ ํŒจํ‚ค์ง€๋ฅผ ๋นŒ๋“œํ•ด์•ผ ํ•จ.

References

MXNet

OpenCV

(Optional) ์‚ฝ์งˆ๊ธฐ

์•„๋ž˜ ์ œ์•ˆ ๋ฐฉ๋ฒ•๋“ค์€ ํฌ๋Ÿผ์—์„œ ์ œ์•ˆ๋œ ๋ฐฉ๋ฒ•๋“ค๋กœ ์‚ฝ์งˆ๊ธฐ๋ฅผ ๊ธฐ๋กํ•ด ๋‘ . ๊ณง๋ฐ”๋กœ Installing OpenCV ๋กœ ๋„˜์–ด๊ฐ€๋„ ๋ฌด๋ฐฉํ•จ.

์ œ์•ˆ ๋ฐฉ๋ฒ• 1: mxnet-jetson ํŒจํ‚ค์ง€ ์„ค์น˜

  • ์‹คํ—˜ ๊ฒฐ๊ณผ: mxnet 1.2.1 ๊ธฐ์ค€์ด๋ฏ€๋กœ ์—ฌ์ „ํžˆ ๋™์ผํ•œ ๋ฌธ์ œ ๋ฐœ์ƒ

pip install mxnet-jetson

์ œ์•ˆ ๋ฐฉ๋ฒ• 2. MXNet 1.4.1 prebuilt-package ์„ค์น˜

python2 ๊ธฐ์ค€

sudo apt-get install -y git build-essential libatlas-base-dev libopencv-dev graphviz python-pipsudo 
pip install mxnet-1.4.0-cp27-cp27mu-linux_aarch64.whl

python3 ๊ธฐ์ค€

sudo apt-get install -y git build-essential libatlas-base-dev libopencv-dev graphviz python3-pipsudo 
pip install mxnet-1.4.0-cp36-cp36m-linux_aarch64.whl
  • ์‹คํ—˜ ๊ฒฐ๊ณผ: libopencv_imgcodecs.so.3.3 ๊ด€๋ จ ์—๋Ÿฌ ๋ฐœ์ƒ. (python2/3 ๋™์ผ)

  • ์ด๋Š” pre-compiled ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ OpenCV 3.3์„ ์ธ์Šคํ†จํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  OpenCV ์˜์กด์„ฑ์„ ํฌํ•จ์‹œ์ผœ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋กœ, ๊ฒฐ๊ตญ OpenCV 3.3์„ ๋”ฐ๋กœ ์ธ์Šคํ†จํ•ด์•ผ ํ•จ.

>>> import mxnet

Pdb)continue
 Traceback (most recent call last):
 File โ€œ/usr/lib/python3.6/pdb.pyโ€, line 1667, in main
 pdb._runscript(mainpyfile)
 File โ€œ/usr/lib/python3.6/pdb.pyโ€, line 1548, in _runscript
 self.run(statement)
 File โ€œ/usr/lib/python3.6/bdb.pyโ€, line 434, in run
 exec(cmd, globals, locals)
 File โ€œ<string>โ€, line 1, in <module>
 File โ€œ/home/lycaass/mximport.pyโ€, line 1, in <module>
 import mxnet
 File โ€œ/usr/local/lib/python3.6/dist-packages/mxnet/*init*.pyโ€, line 24, in <module>
 from .context import Context, current_context, cpu, gpu, cpu_pinned
 File โ€œ/usr/local/lib/python3.6/dist-packages/mxnet/context.pyโ€, line 24, in <module>
 from .base import classproperty, with_metaclass, _MXClassPropertyMetaClass
 File โ€œ/usr/local/lib/python3.6/dist-packages/mxnet/base.pyโ€, line 213, in <module>
 _LIB = _load_lib()
 File โ€œ/usr/local/lib/python3.6/dist-packages/mxnet/base.pyโ€, line 204, in _load_lib
 lib = ctypes.CDLL(lib_path[0], ctypes.RTLD_LOCAL)
 File โ€œ/usr/lib/python3.6/ctypes/*init*.pyโ€, line 348, in *init*
 self._handle = _dlopen(self._name, mode)
 OSError: libopencv_imgcodecs.so.3.3: cannot open shared object file: No such file or directory

์ œ์•ˆ ๋ฐฉ๋ฒ• 3: MXNet 1.6.0 prebuilt-package ์„ค์น˜

  • ์‹คํ—˜ ๊ฒฐ๊ณผ: ๋ฐฉ๋ฒ• 2์™€ ๋™์ผํ•œ ๋ฌธ์ œ ๋ฐœ์ƒ

  • ๊ฒฐ๊ตญ OpenCV 3.3์„ ์„ค์น˜ํ•˜๊ฑฐ๋‚˜, MXNet์„ ์žฌ์ปดํŒŒ์ผํ•ด์•ผ ํ•จ.

  • sudo-apt ilbopencv-dev python-opencv๋กœ ์„ค์น˜ํ•˜๋ฉด ๋ฒ„์ „ ์ถฉ๋Œ ๋ฐœ์ƒ! (libopencv-dev: 4.1.1, python-opencv: 3.2.0)

Installing OpenCV

์•„๋ž˜ ์„ค์น˜ ๋ฐฉ๋ฒ•๋“ค์€ pip, numpy, scipy, cmake๊ฐ€ ์ด๋ฏธ ์„ค์น˜๋˜์—ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•จ. ํŠนํžˆ scipy ์ปดํŒŒ์ผ์ด ์ƒ๊ฐ๋ณด๋‹ค ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์—, ๋ณ„๋„๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœ

MXNet ์ปดํŒŒ์ผ ์‹œ OpenCV๋ฅผ ์ œ์™ธํ•˜๊ณ  ์ปดํŒŒ์ผ ๊ฐ€๋Šฅํ•˜๋‚˜, ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ–ฅํ›„ inference ๋””๋ฒ„๊น…์— ๋‚œํ•ญ์„ ๊ฒช๊ธฐ์— ํ•œ๊บผ๋ฒˆ์— ์„ค์น˜ํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœ

1) pkg-config์œผ๋กœ ํ˜„์žฌ ์„ค์น˜๋œ OpenCV ํ™•์ธ

Jetson Nano์˜ jetpack 4.3์—์„œ OpenCV 3.3.1์ด ๋””ํดํŠธ๋กœ ๊น”๋ ค ์žˆ๋‹ค๊ณ  ํ•˜๋Š”๋ฐ, ๋ณธ์ธ์˜ Jetson Nano์—์„œ๋Š” ์ธ์‹์ด ๋˜์ง€ ์•Š์Œ.

pkg-config opencv --modversion

2) ์‰˜์Šคํฌ๋ฆฝํŠธ ๋‹ค์šด๋กœ๋“œ

OPENCV_GENERATE_PKGCONFIG๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•˜๋ฉฐ, ์ด๋Š” ์‰˜์Šคํฌ๋ฆฝํŠธ์— ๋ชจ๋‘ ๋ฐ˜์˜ํ•ด ๋†“์•˜์Œ.

#!/bin/bash
#
# Copyright (c) 2018, NVIDIA CORPORATION.  All rights reserved.
#
# NVIDIA Corporation and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA Corporation is strictly prohibited.
#
# Modified by Daekeun Kim
# [Mofidifations]
# - Activated OPENCV_GENERATE_PKGCONFIG
# - Removed the script; sudo apt-get install -y python2.7-dev python3.6-dev python-dev python-numpy python3-numpy
#   (Assume we have installed python and numpy)
# - Removed the script due to version conflicting; sudo apt-get install -y python-opencv python3-opencv
#   (The latest version of python-opencv is 3.2.0, not 3.3.x or 4.x)
if [ "$#" -ne 1 ]; then
    echo "Usage: $0 <Install Folder>"
    exit
fi
folder="$1"
user="nvidia"
passwd="nvidia"
echo "** Remove OpenCV3.3 first"
sudo sudo apt-get purge *libopencv*
echo "** Install requirement"
sudo apt-get update
sudo apt-get install -y build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install -y libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
sudo apt-get install -y libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev
sudo apt-get install -y libv4l-dev v4l-utils qv4l2 v4l2ucp
sudo apt-get install -y curl
sudo apt-get update
echo "** Download opencv-4.1.1"
cd $folder
curl -L https://github.com/opencv/opencv/archive/4.1.1.zip -o opencv-4.1.1.zip
curl -L https://github.com/opencv/opencv_contrib/archive/4.1.1.zip -o opencv_contrib-4.1.1.zip
unzip opencv-4.1.1.zip 
unzip opencv_contrib-4.1.1.zip 
cd opencv-4.1.1/
echo "** Building..."
mkdir release
cd release/
cmake -D WITH_CUDA=ON -D CUDA_ARCH_BIN="5.3" -D CUDA_ARCH_PTX="" -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-4.1.1/modules -D WITH_GSTREAMER=ON -D WITH_LIBV4L=ON -D BUILD_opencv_python2=ON -D BUILD_opencv_python3=ON -D BUILD_TESTS=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_EXAMPLES=OFF -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D OPENCV_GENERATE_PKGCONFIG=ON ..
make -j3
sudo make install
echo "** Install opencv-4.1.1 successfully"
echo "** Bye :)"

opencv4.sh

3) ์‰˜์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰

์•ฝ 4์‹œ๊ฐ„ ์†Œ์š”๋จ. ์„ค์น˜ ํ›„์—๋Š” ์žฌ๋ถ€ํŒ…์„ ์ˆ˜ํ–‰ํ•ด์•ผ import๊ฐ€ ์ •์ƒ ๋™์ž‘ (์˜ˆ: import cv2)

mkdir opencv411
chmod 755 opencv4.sh
sudo ./opencv4.sh opencv411

4) pkg-config ์„ค์ •

์ตœ์‹  OpenCV๋Š” OPENCV_GENERATE_PKGCONFIG ์˜ต์…˜์„ ํ™œ์„ฑํ™”ํ•ด๋„ pkg-config๋ฅผ ์ธ์‹ํ•˜์ง€ ๋ชปํ•˜๋Š” ๋ฌธ์ œ ๋ฐœ์ƒ. ์ด๋ฅผ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ํ•ด๊ฒฐ ๊ฐ€๋Šฅ.

cd /usr/local/lib/pkgconfig
cp opencv4.pc opencv.pc
pkg-config opencv --modversion

> 4.1.1

5) (Optional) ํ…Œ์ŠคํŠธ

cd opencv411/opencv-4.1.1/samples/python
python opt_flow.py
jetson_release

6) (Optional) ์›น์บ  ํ…Œ์ŠคํŠธ

์›น์บ ์ด ์ •์ƒ์ ์œผ๋กœ ์ธ์‹๋˜๋Š”์ง€ ํ™•์ธ

ls /dev/video0

https://github.com/JetsonHacksNano/CSI-Camera ์˜ ์ฝ”๋“œ๋ฅผ git clone ํ›„ ํ…Œ์ŠคํŠธ

git clone https://github.com/JetsonHacksNano/CSI-Camera.git
cd CSI-Camera
gst-launch-1.0 nvarguscamerasrc sensor_id=0 ! nvoverlaysink

์™ผ์ชฝ ์ปค๋„ฅํ„ฐ์— ์›น์บ  ์—ฐ๊ฒฐ ์‹œ sensor_id = 0์ด๊ณ , ์˜ค๋ฅธ์ชฝ ์ปค๋„ฅํ„ฐ์— ์—ฐ๊ฒฐ ์‹œ sensor_id = 1

OpenCV Haar-cascade Face Detector ํ…Œ์ŠคํŠธ; ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋ณต๋ถ™ํ•˜์—ฌ face-detector.py๋กœ ์ €์žฅ ํ›„ python face-detector.py๋กœ ์‹คํ–‰

import cv2
import numpy as np
HAAR_CASCADE_XML_FILE_FACE = "/usr/share/opencv4/haarcascades/haarcascade_frontalface_default.xml"
GSTREAMER_PIPELINE = 'nvarguscamerasrc ! video/x-raw(memory:NVMM), width=3280, height=2464, format=(string)NV12, framerate=21/1 ! nvvidconv flip-method=0 ! video/x-raw, width=960, height=616, format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR ! appsink'

def faceDetect():
    # Obtain face detection Haar cascade XML files from OpenCV
    face_cascade = cv2.CascadeClassifier(HAAR_CASCADE_XML_FILE_FACE)

    # Video Capturing class from OpenCV
    video_capture = cv2.VideoCapture(GSTREAMER_PIPELINE, cv2.CAP_GSTREAMER)
    if video_capture.isOpened():
        cv2.namedWindow("Face Detection Window", cv2.WINDOW_AUTOSIZE)

        while True:
            return_key, image = video_capture.read()
            if not return_key:
                break

            grayscale_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
            detected_faces = face_cascade.detectMultiScale(grayscale_image, 1.3, 5)

            # Create rectangle around the face in the image canvas
            for (x_pos, y_pos, width, height) in detected_faces:
                cv2.rectangle(image, (x_pos, y_pos), (x_pos + width, y_pos + height), (0, 0, 0), 2)

            cv2.imshow("Face Detection Window", image)

            key = cv2.waitKey(30) & 0xff
            # Stop the program on the ESC key
            if key == 27:
                break

        video_capture.release()
        cv2.destroyAllWindows()
    else:
        print("Cannot open Camera")

if __name__ == "__main__":
    faceDetect()

Installing MXNet

MXNet ์ปดํŒŒ์ผ์— ์ตœ์†Œ 5์‹œ๊ฐ„ ์ด์ƒ ์†Œ์š”๋˜๋ฏ€๋กœ nohup์œผ๋กœ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…์„ ๊ฑธ์–ด๋†“๊ณ  ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœ

2020๋…„ 7์›” ๊ธฐ์ค€์œผ๋กœ 1.6.0์ด ์ตœ์‹  ๋ฒ„์ „์ด์ง€๋งŒ, ํ˜ธํ™˜์„ฑ ์ธก๋ฉด์—์„œ ์ข‹์ง€ ์•Š๊ณ (๋‹จ, GluonNLP๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด 1.6.0 ๊ถŒ์žฅ) SageMaker๋„ ํ˜„์žฌ 1.4.1์„ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ 1.4.1 ์„ค์น˜ ๊ถŒ์žฅ (1.5.1๋„ ๋ฌด๋ฐฉํ•˜๋ฉฐ, ์ตœ๊ทผ ํฌ๋Ÿผ๊ธ€์—์„œ๋Š” 1.5.1์„ ๋” ๊ถŒ์žฅํ•จ). ์ฐธ๊ณ ๋กœ, MXNet์€ ํ•˜์œ„ํ˜ธํ™˜์„ฑ ๋ฐ ์ƒ์œ„ํ˜ธํ™˜์„ฑ์ด ์—†๊ธฐ์— ๋™์ผํ•œ ๋ฒ„์ „์œผ๋กœ ๋งž์ถฐ์•ผ ํ•จ.

  • 1.6.0 : Precompiled ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ธฐ์ค€์œผ๋กœ๋Š” CUDA 10.2์ด๋ฉฐ, ์ปดํ“จํ„ฐ ๋น„์ „์—์„œ๋Š” ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์ œ๋“ค ๋ฐœ์ƒํ•˜๊ธฐ์— ์ถ”์ฒœํ•˜์ง€ ์•Š์Œ. ๋‹จ, ์ž์—ฐ์–ด์ฒ˜๋ฆฌ ํ•™์Šต์„ ์œ„ํ•ด GluonNLP ์„ค์น˜ ์‹œ์—๋Š” 1.6.0๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•จ

  • 1.4.1~1.5.1: ์ถ”์ฒœ ๋ฒ„์ „ & CUDA 10.0

  • 1.2.1: Outdated & CUDA 9.0

1) swap ์ƒ์„ฑ (Jetson Nano์— ๊ธฐ๋ณธ ๋‚ด์žฅ๋œ 4๊ธฐ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ๋กœ๋Š” ๋ถ€์กฑํ•˜๋ฏ€๋กœ)

fallocate -l 8G swapfile
sudo chmod 600 swapfile
sudo mkswap swapfile
sudo swapon swapfile

2) ์˜์กด์„ฑ ํŒจํ‚ค์ง€ ์„ค์น˜

sudo apt-get update
sudo apt-get install -y git build-essential libatlas-base-dev graphviz
sudo pip install --upgrade setuptools
sudo pip install numpy==1.15.2
sudo pip install graphviz jupyter

3) Build MXNet (์•ฝ 5-6์‹œ๊ฐ„ ์†Œ์š”๋จ)

make -j3 ์˜ต์…˜์œผ๋กœ ์‹คํ–‰ ์‹œ ๊ฐ„ํ—์ ์œผ๋กœ ๋‹ค์šด๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ๋งŒ์•ฝ ์ค‘๊ฐ„์— ๋‹ค์šด๋˜๋ฉด make -j2๋กœ ๋ณ€๊ฒฝ

git clone https://github.com/apache/incubator-mxnet.git --branch v1.4.x --recursive
cd incubator-mxnet/
cp make/config.mk .
sed -i 's/USE_CUDA = 0/USE_CUDA = 1/' config.mk
sed -i 's/USE_CUDA_PATH = NONE/USE_CUDA_PATH = \/usr\/local\/cuda/' config.mk
sed -i 's/USE_CUDNN = 0/USE_CUDNN = 1/' config.mk
sed -i '/USE_CUDNN/a CUDA_ARCH := -gencode arch=compute_53,code=sm_53' config.mk
make -j3

4) Install MXNet

cd python
sudo python setup.py install
cd ..
export MXNET_HOME=$(pwd)
echo "export PYTHONPATH=$MXNET_HOME/python:$PYTHONPATH" >> ~/.bashrc
source ~/.bashrc

5) libopencv-dev ์„ค์น˜

OpenCV๋ฅผ ์ธ์Šคํ†จํ•ด๋„ ์ผ๋ถ€ ์˜์กด์„ฑ ํŒŒ์ผ๋“ค์„ MXNet์—์„œ ์ฐพ์ง€ ๋ชปํ•˜๋ฏ€๋กœ libopencv-dev ์„ค์น˜๋กœ ํ•ด๊ฒฐ ๊ฐ€๋Šฅ. ์ฐธ๊ณ ๋กœ libopencv-dev ๋ฒ„์ „์€ 4.1.1๋กœ ๋ฒ„์ „ ์ถฉ๋Œ ๋ฌธ์ œ ์—†์Œ.

sudo apt-get install libopencv-dev

6) (Optional) ํ…Œ์ŠคํŠธ

>>> import mxnet as mx
>>> a = mx.nd.ones((2,3), mx.cpu())
>>> print(a*2)

[[2. 2. 2.]
 [2. 2. 2.]
<NDArray 2x3 @cpu(0)>

>>> import mxnet as mx
>>> a = mx.nd.ones((2,3), mx.gpu()) # ์ฒ˜์Œ ์‹คํ–‰ ์‹œ ์•ฝ 30์ดˆ ์ •๋„ ๋”œ๋ ˆ์ด๋จ
>>> print(a*2)

[[2. 2. 2.]
 [2. 2. 2.]
<NDArray 2x3 @gpu(0)>

Last updated