openVINO 2022.1(Raspberry Pi OS(64bit)向け)のbuild

Raspberry Pi OS(64bit)向けopenVINO 2022.1のbuild

概要

openVINO 2022.1はRaspberry Pi OS(64bit)向けのバイナリがリリースされていないので、自力でbuildしてみます。

今回もUbuntu上のDockerコンテナを使用しましたが、おそらくWindowsのDocker Desktop for Windowsでも出来ると思います。

前回はPythonを諦めてクロスコンパイルする方法とbuild時間を諦めてセルフコンパイル(エミュレーション)する方法を使いましたが、
今回はPython以外をクロスコンパイル、Python関連部をセルフコンパイル(エミュレーション)して生成物をマージする方法をとってみます。

準備

Dockerのインストールはこちらを参照。

qemuのインストール

ARMのバイナリを実行するため、QEMUをインストールしておきます。

sudo apt update
sudo apt install qemu-user-static 

[!NOTE] QEMUの情報: https://github.com/multiarch/qemu-user-static

作業用ディレクトリの準備

適当なディレクトリを作成して移動。

mkdir -p /work/docker_work/ov_2022.1_pi64 && cd /work/docker_work/ov_2022.1_pi64

openVINO の gitリポジトリを clone

workディレクトリを作成し、openvino と openvino_contrib のリポジトリをcloneします。
必ず同じディレクトリに(後の指定がめんどくさくなるので)。

mkdir work
git -C ./work clone  -b 2022.1.1 --recursive --depth 1 https://github.com/openvinotoolkit/openvino.git
git -C ./work clone  https://github.com/openvinotoolkit/openvino_contrib.git
git -C ./work/openvino_contrib checkout 1a28b530ab40d2ad79ab29021dfddfbbc7d2db0b
git -C ./work/openvino_contrib submodule update --init --recursive --depth 1

[!NOTE] openvino_contrib の2022.1だと一部のノードが未対応とエラーになるため、対応済みのcommitを使用します。
tagが振られていないので、commit IDを指定してcheckoutします。
これ以降のcommitではopenvinoのバージョン2022.2が必要になります。

[!TIP] tagやbranchが設定されていない場合はcloneでcheckoutするバージョンを指定できないため、 一旦cloneしてからcommit IDを指定してcheckoutします。
submoluleのcheckoutは対象のバージョンをcheckoutしてから行います。

[!NOTE] openvino_contrib の最新commit(試した時点ではcommit ID fd2ac364435757d23a9b3e91d67235b5e6555bf9)を使用する場合は openvinoのバージョン2022.2を使用する必要がありますが、試した時点で 2022.2.0.dev20220829 がリリースされているので これを使用します。

mkdir work
git -C ./work clone  -b 2022.2.0.dev20220829  --recursive --depth 1 https://github.com/openvinotoolkit/openvino.git
git -C ./work clone  https://github.com/openvinotoolkit/openvino_contrib.git
git -C ./work/openvino_contrib checkout fd2ac364435757d23a9b3e91d67235b5e6555bf9
git -C ./work/openvino_contrib submodule update --init --recursive --depth 1

2022.2.0正式リリース後はこんな感じになるのかな?

mkdir work
git -C ./work clone  -b 2022.2.0  --recursive --depth 1 https://github.com/openvinotoolkit/openvino.git
git -C ./work clone  -b 2022.2    --recursive --depth 1 https://github.com/openvinotoolkit/openvino_contrib.git

この場合、NVIDIA GPUのpluginのbuildでエラーになるため、以下のcmakeのオプションに以下のオプションを追加します。

      -D BUILD_nvidia_plugin=OFF

[!NOTE] git submodule にも --depth 1をつけると早いし、ディスクの節約にもなる。

openVINOのBuild(クロスコンパイル)

クロスコンパイルでpython関連以外の部分をbuildします。

Dockerコンテナの作成&起動

Dockerfileを作成

mkdir crossしてから、以下の内容でcross/Dockerfileを作成します。

cross/Dockerfile

FROM amd64/debian:bullseye

USER root

RUN dpkg --add-architecture arm64 && \
    apt-get update && \
    apt-get install -y --no-install-recommends \
    build-essential \
    crossbuild-essential-arm64 \
    cmake \
    automake \
    git \
    git-lfs \
    libtool \
    autoconf \
    shellcheck \
    patchelf \
    curl \
    wget \
    ccache \
    unzip \
    libssl-dev \
    ca-certificates:arm64 \
    libboost-regex-dev:arm64 \
    libgtk2.0-dev:arm64 \
    pkg-config \
    libenchant-2-dev:arm64 \
    libcairo2-dev:arm64 \
    libpango1.0-dev:arm64 \
    libglib2.0-dev:arm64 \
    gstreamer1.0-plugins-base \
    libopenblas-dev:arm64 \
    libusb-1.0-0-dev:arm64 \
    libavcodec-dev:arm64 \
    libavformat-dev:arm64 \
    libswscale-dev:arm64 \
    libgstreamer1.0-dev:arm64 \
    libgstreamer-plugins-base1.0-dev:arm64 \
    libprotobuf-dev:arm64 \
    libprotoc-dev:arm64 \
    protobuf-compiler \
    python3-minimal \
    libpython3-dev:arm64 \
    python3-pip \
    python3-enchant \
    python3-setuptools \
    python3-numpy \
    cython3 \
    scons

RUN git config --global user.name "«ユーザ名»" && \
    git config --global user.email "«メールアドレス»"

RUN installed_cmake_ver=3.23.2 && \
    wget "https://github.com/Kitware/CMake/releases/download/v${installed_cmake_ver}/cmake-${installed_cmake_ver}.tar.gz" && \
    tar xf cmake-${installed_cmake_ver}.tar.gz && \
    (cd cmake-${installed_cmake_ver} && ./bootstrap --parallel="$(nproc --all)" && make --jobs="$(nproc --all)" && make install) && \
    rm -rf cmake-${installed_cmake_ver} cmake-${installed_cmake_ver}.tar.gz

WORKDIR /work

[!TIP] git config ~ を設定してないと、cmake中にgit cloneが失敗します

[!NOTE] cmakeは新しめのをインストールしておきたいので、3.23.2をbuildして使用しています。
もしかすると、aptでインストールしたものをそのまま使っても大丈夫かもしれませんが。

Dockerイメージ作成

DockerfileからDockerイメージを作成します。
以下ではイメージ名に ov_2022.1_pi64_cross を使用。

docker image build -t ov_2022.1_pi64_cross cross

[!TIP] cacheを使わずimage buildしたい場合は--no-cacheオプションを追加します。
以前に作ったイメージのキャッシュを使ってapt installがエラーになったことがあったので。
(デフォルトのリポジトリに変更があったらしい)

Dockerコンテナ作成

DockerイメージからDockerコンテナを作成します。
以下ではコンテナ名に ov_2022.1_pi64_cross_2 を使用。

docker container create -it -v $PWD/work:/work --name ov_2022.1_pi64_cross_2 ov_2022.1_pi64_cross /bin/bash

[!TIP] Windowsでは$PWDの代わりに%CD%を使用

Dockerコンテナ起動

Dockerコンテナを起動します。

docker container start -ia ov_2022.1_pi64_cross_2

[!TIP] Dockerコンテナに別コンソールから入るにはこれ

docker exec -it ov_2022.1_pi64_cross_2 /bin/bash

本番

ここからコンテナ内

shell変数の設定とbuildディレクトリの作成

WORK_DIR=/work
OV_TOP=${WORK_DIR}/openvino/
CONTRIB_TOP=${WORK_DIR}/openvino_contrib

cd ${OV_TOP}
mkdir build && cd build

cmake実行

cmake -D CMAKE_BUILD_TYPE=Release \
      -D CMAKE_INSTALL_PREFIX=${WORK_DIR}/intel/openvino \
      -D CMAKE_TOOLCHAIN_FILE=${OV_TOP}/cmake/arm64.toolchain.cmake \
      -D CMAKE_C_FLAGS="-pthread" \
      -D CMAKE_CXX_FLAGS="-pthread" \
      -D ENABLE_BEH_TESTS=OFF \
      -D ENABLE_CLDNN=OFF \
      -D ENABLE_TESTS=OFF \
      -D ENABLE_FUNCTIONAL_TESTS=OFF \
      -D THREADING=SEQ \
      -D IE_EXTRA_MODULES=${CONTRIB_TOP}/modules \
      -D BUILD_java_api=OFF \
      ${OV_TOP} 2>&1 | tee cmake.log

make

make --jobs=$(nproc --all) 2>&1 | tee build.log

install

make install 2>&1 | tee install.log

これを実行すると。 /work/intel/openvino にインストールされます。
インストール先を変更したい場合はcmakeの オプションの-DCMAKE_INSTALL_PREFIX=${WORK_DIR}/intel/openvinoの部分を変更すれば良いけど、 どうせアーカイブしてコピーして使うからあんまり関係ないとおもう。

クロスコンパイル終了

クロスコンパイルはここまでなので、コンテナから抜ける。

openVINOのBuild(セルフコンパイル)

セルフコンパイルでpython関連部分をbuildします。
cythonを使うときにクロスコンパイルする方法が分からないので、セルフコンパイルで。

Dockerコンテナの作成&起動

Dockerfileを作成

mkdir emuしてから、以下の内容でemu/Dockerfileを作成します。

python部だけなので、こんなにライブラリとか要らない気もしますが、全部セルフコンパイルするときのことも考えて 全部入りのイメージを作っておきます。

emu/Dockerfile

FROM arm64v8/debian:bullseye

USER root

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
    build-essential \
    cmake \
    automake \
    git \
    git-lfs \
    libtool \
    autoconf \
    shellcheck \
    patchelf \
    curl \
    wget \
    ccache \
    unzip \
    libssl-dev \
    ca-certificates \
    libboost-regex-dev \
    libgtk2.0-dev \
    pkg-config \
    libenchant-2-dev \
    libcairo2-dev \
    libpango1.0-dev \
    libglib2.0-dev \
    gstreamer1.0-plugins-base \
    libopenblas-dev \
    libusb-1.0-0-dev \
    libavcodec-dev \
    libavformat-dev \
    libswscale-dev \
    libgstreamer1.0-dev \
    libgstreamer-plugins-base1.0-dev \
    libprotobuf-dev libprotoc-dev protobuf-compiler \
    python3-minimal \
    libpython3-dev \
    python3-pip \
    python3-enchant \
    python3-setuptools \
    python3-numpy \
    cython3 \
    scons

RUN git config --global user.name "«ユーザ名»" && \
    git config --global user.email "«メールアドレス»"

RUN installed_cmake_ver=3.23.2 && \
    wget "https://github.com/Kitware/CMake/releases/download/v${installed_cmake_ver}/cmake-${installed_cmake_ver}.tar.gz" && \
    tar xf cmake-${installed_cmake_ver}.tar.gz && \
    (cd cmake-${installed_cmake_ver} && ./bootstrap --parallel="$(nproc --all)" && make --jobs="$(nproc --all)" && make install) && \
    rm -rf cmake-${installed_cmake_ver} cmake-${installed_cmake_ver}.tar.gz

WORKDIR /work

Dockerイメージ作成

DockerfileからDockerイメージを作成します。
以下ではイメージ名に ov_2022.1_pi64_emu を使用。

docker image build -t ov_2022.1_pi64_emu emu

Dockerコンテナ作成

DockerイメージからDockerコンテナを作成します。
以下ではコンテナ名に ov_2022.1_pi64_emu_2 を使用。

docker container create -it -v $PWD/work:/work --name ov_2022.1_pi64_emu_2 ov_2022.1_pi64_emu /bin/bash

[!NOTE] WARNING: The requested image's platform (linux/arm/v8) does not match the detected host platform (linux/amd64) and no specific platform was requested
と言われるけど大丈夫

Dockerコンテナ起動

Dockerコンテナを起動します。

docker container start -ia ov_2022.1_pi64_emu_2

本番

ここからコンテナ内

shell変数の設定とbuildディレクトリの作成

WORK_DIR=/work
OV_TOP=${WORK_DIR}/openvino/
CONTRIB_TOP=${WORK_DIR}/openvino_contrib

cd ${OV_TOP}
mkdir build_python && cd build_python

cmake実行

cmake -D CMAKE_BUILD_TYPE=Release \
      -D CMAKE_INSTALL_PREFIX=${WORK_DIR}/intel/openvino \
      -D ENABLE_PYTHON=ON \
      -D InferenceEngineDeveloperPackage_DIR=${OV_TOP}/build \
      ${OV_TOP}/src/bindings/python 2>&1 | tee cmake.log

[!TIP] CMAKE_INSTALL_PREFIXの設定はクロスコンパイルのときと同じ設定にしてください。

[!NOTE] pyenvでインストールしたpythonなど、デフォルトでないpythonを使用する場合に指定します。
(以下の設定値はubuntu 22.04の標準インストールの場合のパスなのであまり参考にならないかも)

  -D PYTHON_EXECUTABLE=/usr/bin/python3.8 \
  -D PYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.8.so \
  -D PYTHON_INCLUDE_DIR=/usr/include/python3.8 \
  -D PYTHON_MODULE_EXTENSION=".so" \

make

make --jobs=$(nproc --all) 2>&1 | tee build.log

install

make install 2>&1 | tee install.log

これを実行すると。 /work/intel/openvino にインストールされます。

セルフコンパイル終了

セルフコンパイルはここまでなので、コンテナから抜けます。

インストール媒体の作成

ホスト側のworkディレクトリ内を見ると、intelディレクトリが出来ているので、ここをtarなどで固めておきます。

cd work
tar czvf ov1.tar.gz intel/

このov1.tar.gzをRaspberryPiにコピーして展開します。

RaspberryPiへのインストール

インストール

最終的に作成したov1.tar.gzをRaspberryPiの適当なディレクトリに展開します。
今回は/projディレクトリに展開しておきます。

pushd /proj/
tar xzvf ov1.tar.gz 
popd

これで/proj/intel/openvinoディレクトリにインストールされました。

環境変数の設定

環境変数の設定のため、以下を実行します。
shell起動の度に実行が必要なので~/.bashrcなどに書いておくと良いです。

source /proj/intel/openvino/setupvars.sh 

udevルールの設定

以下のスクリプトを実行すればNCS2を挿せば認識されるようになります。

/proj/intel/openvino/install_dependencies/install_NCS_udev_rules.sh 

openCVのインストール

openCVの必要になるので、インストールしておきます。
今回はお手軽にpipでインストール。

pip install opencv-python

動作確認

動作確認用のプログラムはhttps://github.com/ippei8jp/ov_trial_2022.1 とかにあります。
でもモデルのダウンロード/コンバートはRaspberryPiではできないので、UbuntuやWondowsで実行したものをコピーして使用してください。