Ubuntu 22.04(jammy, arm64) + Raspberry Pi 4(model B)でmediapipe 0.10.1をビルド
June 21, 2023
Categories: ubuntu raspberrypi mediapipe
参考
自分でビルドするのはめんどくさい人向け
ビルド済みバイナリ(mediapipe-0.10.1)を用意しました。
Ubuntu用はバージョンがdev
になっていますが、中身は0.10.1
です。
- [Ubuntu 22.04(arm64)用] mediapipe-dev-cp310-cp310-linux_aarch64.whl
- [Raspberry Pi OS bullseye(arm64)用] mediapipe-0.10.1-cp39-cp39-linux_aarch64.whl
bazeliskの導入
とりあえず~/apps/binに入れておく。PATHも通しておいたほうがよい。
1
2
3
4
5
% mkdir -p ~/apps/bin
% curl -L -o ~/apps/bin/bazelisk https://github.com/bazelbuild/bazelisk/releases/download/v1.11.0/bazelisk-linux-arm64
% (cd ~/apps/bin; ln -sf bazelisk bazel)
% chmod +x ~/apps/bin/bazelisk
% PATH="${HOME}/apps/bin:${PATH}"
ビルドに必要なものの用意
1
2
3
4
% sudo apt install build-essential python3-dev python3-setuptools cmake protobuf-compiler python3-numpy
% git clone https://github.com/google/mediapipe
% cd mediapipe
% git checkout v0.10.1
setup.py
のバージョン情報を更新する。
1
% sed -i "s/__version__ = 'dev'/__version__ = '0.10.1'/" setup.py
third_party/BUILD
を編集し、不要な機能を除外する。
同様に不要なライブラリのリンクをしないようにする。
また、carotene_o4t
を無効化する。
1
2
3
% sed -i -e "/\"imgcodecs\"/d;/\"calib3d\"/d;/\"features2d\"/d;/\"highgui\"/d;/\"video\"/d;/\"videoio\"/d" \
-e "/-ljpeg/d;/-lpng/d;/-ltiff/d;/-lImath/d;/-lIlmImf/d;/-lHalf/d;/-lIex/d;/-lIlmThread/d;/-lrt/d;/-ldc1394/d;/-lavcodec/d;/-lavformat/d;/-lavutil/d;/-lswscale/d;/-lavresample/d" \
-e 's/"WITH_WEBP": "OFF",/"WITH_WEBP": "OFF",\n "ENABLE_NEON": "OFF",\n "WITH_TENGINE": "OFF",/' third_party/BUILD
編集したthird_party/BUILD
のdiffは下記の通り。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
% git diff third_party/BUILD
diff --git a/third_party/BUILD b/third_party/BUILD
index e2044cf..0100547 100644
--- a/third_party/BUILD
+++ b/third_party/BUILD
@@ -76,12 +76,6 @@ load("@rules_foreign_cc//tools/build_defs:cmake.bzl", "cmake_external")
# linker, so if library A depends on library B, library B must come _after_.
# Hence core is at the bottom.
OPENCV_MODULES = [
- "calib3d",
- "features2d",
- "highgui",
- "video",
- "videoio",
- "imgcodecs",
"imgproc",
"core",
]
@@ -113,6 +107,8 @@ cmake_external(
"WITH_PNG": "ON",
"WITH_TIFF": "ON",
"WITH_WEBP": "OFF",
+ "ENABLE_NEON": "OFF",
+ "WITH_TENGINE": "OFF",
# Optimization flags
"CV_ENABLE_INTRINSICS": "ON",
"WITH_EIGEN": "ON",
@@ -149,25 +145,10 @@ cmake_external(
# the build, and so depends on what is installed on the local system.
# After building, the linkopts for the current setup can be extracted
# from lib/pkgconfig/opencv.pc in bazel-out
- "-ljpeg",
- "-lpng",
"-lz",
- "-ltiff",
- "-lImath",
- "-lIlmImf",
- "-lIex",
- "-lHalf",
- "-lIlmThread",
- "-ldc1394",
- "-lavcodec",
- "-lavformat",
- "-lavutil",
- "-lswscale",
- "-lavresample",
"-ldl",
"-lm",
"-lpthread",
- "-lrt",
],
shared_libraries = select({
"@bazel_tools//src/conditions:darwin": ["libopencv_%s.%s.dylib" % (module, OPENCV_SO_VERSION) for module in OPENCV_MODULES],
編集が完了したら、早速ビルドを開始する。
1
2
3
% PATH="${HOME}/apps/bin:${PATH}"
% python3 setup.py gen_protos
% time python3 setup.py bdist_wheel
/usr/bin/python
が存在しないと下記のようなエラーが発生する。
どうやらどこかのスクリプトのShebangで#!/usr/bin/env python
が用いられている模様。
とりあえずsudo ln -s /usr/bin/python3.9 /usr/bin/python
しておけば通った。
1
2
3
4
5
6
7
8
9
10
11
12
13
ERROR: /home/gloria/.cache/bazel/_bazel_gloria/c703987e42a2b396bbfb309c04bccc16/external/org_tensorflow/tensorflow/core/util/BUILD:379:24:
Action external/org_tensorflow/tensorflow/core/util/version_info.cc failed: (Exit 127): bash failed: error executing command
/bin/bash -c 'bazel-out/aarch64-opt-ST-e0f78fafe98f/bin/external/org_tensorflow/tensorflow/tools/git/gen_git_source
--generate "$@" --git_tag_override=${GIT_TAG_OVERRIDE:-}' '' ... (remaining 4 argument(s) skipped)
Use --sandbox_debug to see verbose messages from the sandbox
/usr/bin/env: 'python': No such file or directory
Target //mediapipe/modules/face_detection:face_detection_short_range_cpu failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 4961.073s, Critical Path: 3555.34s
INFO: 2026 processes: 265 internal, 1761 linux-sandbox.
FAILED: Build did NOT complete successfully
python3 setup.py bdist_wheel 2.09s user 3.12s system 0% cpu 1:22:43.05 total
Raspberry Pi 4(modelB 8GB)では、合計3時間程度でビルドできた。 メモリは常に2GB以上必要となるようなので、最低でも4GBモデルが必要となりそう。(2023/04/24追記: 4GBでは足りなかった)
1
python3 setup.py bdist_wheel 19.92s user 19.28s system 0% cpu 2:44:46.69 total
インストール
ビルドしたmediapipeライブラリと、mediapipeの利用に必要なライブラリ群をインストールしておく。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
% sudo apt install cython3 python3-opencv
% pip3 install pillow
% pip3 install ./dist/mediapipe-dev-cp310-cp310-linux_aarch64.whl
Defaulting to user installation because normal site-packages is not writeable
Processing /home/gloria/src/mediapipe/dist/mediapipe-dev-cp310-cp310-linux_aarch64.whl
Collecting absl-py
Downloading absl_py-1.4.0-py3-none-any.whl (126 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 126.5/126.5 KB 1.3 MB/s eta 0:00:00
Collecting flatbuffers>=2.0
Downloading flatbuffers-23.5.26-py2.py3-none-any.whl (26 kB)
Collecting opencv-contrib-python
Downloading opencv_contrib_python-4.7.0.72-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (45.0 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 45.0/45.0 MB 6.1 MB/s eta 0:00:00
Requirement already satisfied: numpy in /usr/lib/python3/dist-packages (from mediapipe==dev) (1.21.5)
Collecting sounddevice>=0.4.4
Downloading sounddevice-0.4.6-py3-none-any.whl (31 kB)
Requirement already satisfied: attrs>=19.1.0 in /usr/lib/python3/dist-packages (from mediapipe==dev) (21.2.0)
Collecting protobuf<4,>=3.11
Downloading protobuf-3.20.3-cp310-cp310-manylinux2014_aarch64.whl (918 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 918.4/918.4 KB 8.7 MB/s eta 0:00:00
Collecting matplotlib
Downloading matplotlib-3.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (11.3 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 11.3/11.3 MB 9.5 MB/s eta 0:00:00
Collecting CFFI>=1.0
Using cached cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (449 kB)
Collecting pillow>=6.2.0
Downloading Pillow-9.5.0-cp310-cp310-manylinux_2_28_aarch64.whl (3.2 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.2/3.2 MB 10.1 MB/s eta 0:00:00
Requirement already satisfied: pyparsing>=2.3.1 in /usr/lib/python3/dist-packages (from matplotlib->mediapipe==dev) (2.4.7)
Collecting kiwisolver>=1.0.1
Downloading kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.4 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 4.3 MB/s eta 0:00:00
Collecting packaging>=20.0
Downloading packaging-23.1-py3-none-any.whl (48 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 48.9/48.9 KB 185.7 kB/s eta 0:00:00
Collecting python-dateutil>=2.7
Using cached python_dateutil-2.8.2-py2.py3-none-any.whl (247 kB)
Collecting fonttools>=4.22.0
Downloading fonttools-4.40.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.2 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.2/4.2 MB 10.3 MB/s eta 0:00:00
Collecting contourpy>=1.0.1
Downloading contourpy-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (283 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 283.9/283.9 KB 10.6 MB/s eta 0:00:00
Collecting cycler>=0.10
Using cached cycler-0.11.0-py3-none-any.whl (6.4 kB)
Collecting pycparser
Using cached pycparser-2.21-py2.py3-none-any.whl (118 kB)
Requirement already satisfied: six>=1.5 in /usr/lib/python3/dist-packages (from python-dateutil>=2.7->matplotlib->mediapipe==dev) (1.16.0)
Installing collected packages: flatbuffers, python-dateutil, pycparser, protobuf, pillow, packaging, opencv-contrib-python, kiwisolver,
fonttools, cycler, contourpy, absl-py, matplotlib, CFFI, sounddevice, mediapipe
Successfully installed CFFI-1.15.1 absl-py-1.4.0 contourpy-1.1.0 cycler-0.11.0 flatbuffers-23.5.26 fonttools-4.40.0 kiwisolver-1.4.4
matplotlib-3.7.1 mediapipe-dev opencv-contrib-python-4.7.0.72 packaging-23.1 pillow-9.5.0 protobuf-3.20.3 pycparser-2.21 python-dateutil-2.8.2 sounddevice-0.4.6
コケた場合の対処法
コケる可能性は無限大。
swap領域を追加する
メモリが不足しコケる場合は、下記のようにswapfileなどを用意して回避する手法もある。 ただし、少なくともUSB-SSDを用いるなどの対策を行わないとSDカードがあっという間に壊れる可能性が高いので注意。 (そもそもビルドのようなストレージに負荷が掛かる作業は、SDカード上では行わない方がよい。)
1
2
3
4
5
6
% sudo dd if=/dev/zero of=/swapfile bs=1M count=4096
% sudo mkswap /swapfile
% sudo swapon /swapfile
% swapon
NAME TYPE SIZE USED PRIO
/swapfile file 4G 1.5M -2
setuptoolsとwheelを最新にする
setup.py
が速攻でコケた時は、mediapipeに限らずだいたいこれ。毎度おなじみ。
1
% python3 -m pip install -U setuptools wheel
下手にディストリパッケージのpip
をインストールするとバージョンやら依存関係やらがぐちゃぐちゃになりがちなので、
get-pip.py
あたりを使った方がよいかもしれない。
(その上でpipenv
などを使うとなおよいかもしれない。)
protobuf-compiler(protoc)を最新にする
ubuntu-22.04では大丈夫なようだが、Raspberry Pi OSなどで動かしたい場合は
protoc
が古すぎてpython3 setup.py gen_protos
がエラーとなる場合がある。
1
2
3
4
% python3 setup.py gen_protos
...
generating proto file: build/lib.linux-aarch64-cpython-39/mediapipe/tasks/cc/components/processors/proto/detection_postprocessing_graph_options_pb2.py
mediapipe/tasks/cc/components/processors/proto/detection_postprocessing_graph_options.proto: This file contains proto3 optional fields, but --experimental_allow_proto3_optional was not set.
このような場合は、bazel同様~/apps
にprotoc
の新しいバイナリを入れておく。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
% curl -L -O https://github.com/protocolbuffers/protobuf/releases/download/v23.3/protoc-23.3-linux-aarch_64.zip
% unzip protoc-23.3-linux-aarch_64.zip -d ~/apps/bin
Archive: protoc-23.3-linux-aarch_64.zip
inflating: apps/bin/protoc
inflating: apps/include/google/protobuf/any.proto
inflating: apps/include/google/protobuf/api.proto
inflating: apps/include/google/protobuf/compiler/plugin.proto
inflating: apps/include/google/protobuf/descriptor.proto
inflating: apps/include/google/protobuf/duration.proto
inflating: apps/include/google/protobuf/empty.proto
inflating: apps/include/google/protobuf/field_mask.proto
inflating: apps/include/google/protobuf/source_context.proto
inflating: apps/include/google/protobuf/struct.proto
inflating: apps/include/google/protobuf/timestamp.proto
inflating: apps/include/google/protobuf/type.proto
inflating: apps/include/google/protobuf/wrappers.proto
inflating: apps/readme.txt
古いバージョンは削除しておきましょう。
1
% sudo apt purge protobuf-compiler
clang-13を用いる
Raspberry Pi OS(bullseye)のgcc(10.2.1 20210110 (Debian 10.2.1-6))だと、ビルド中に下記のようにSegmentation faultによるinternal compiler errorが発生する。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ERROR: /home/gloria/src/mediapipe-0.10.1/mediapipe/framework/stream_handler/BUILD:84:11: Compiling mediapipe/framework/stream_handler/fixed_size_input_stream_handler.cc failed: (Exit 1): gcc failed: error executing command (from target //mediapipe/framework/stream_handler:fixed_size_input_stream_handler) /usr/bin/gcc -U_FORTIFY_SOURCE -fstack-protector -Wall -Wunused-but-set-parameter -Wno-free-nonheap-object -fno-omit-frame-pointer -g0 -O2 '-D_FORTIFY_SOURCE=1' -DNDEBUG -ffunction-sections ... (remaining 56 arguments skipped)
Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging
In file included from <command-line>:
/usr/include/stdc-predef.h: In substitution of 'template<class _Functor, class, class> std::function<std::unique_ptr<mediapipe::InputStreamHandler>(std::shared_ptr<mediapipe::tool::TagMap>, mediapipe::CalculatorContextManager*, const mediapipe::MediaPipeOptions&, bool)>::function(_Functor) [with _Functor = <missing>; <template-parameter-1-2> = <missing>; <template-parameter-1-3> = <missing>]':
mediapipe/framework/stream_handler/fixed_size_input_stream_handler.cc:228:1: required from here
/usr/include/stdc-predef.h:32:94: internal compiler error: Segmentation fault
32 | whether the overall intent is to support these features; otherwise,
| ^
0x7f8c5fbe17 __libc_start_main
../csu/libc-start.c:308
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <file:///usr/share/doc/gcc-10/README.Bugs> for instructions.
Target //mediapipe/modules/face_detection:face_detection_short_range_cpu failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 1608.472s, Critical Path: 1323.53s
INFO: 1122 processes: 321 internal, 801 linux-sandbox.
FAILED: Build did NOT complete successfully
clang-13であれば問題なくビルドできるようだった。
1
2
3
4
5
6
7
% sudo apt install clang-13
% CC=clang
% CXX=clang
% export CC
% export CXX
% python3 setup.py gen_protos
% time python3 setup.py bdist_wheel
ソースコードを展開しなおす
複数回ビルド作業を行ったソースコードから作成したwhlファイルをインストールすると、下記のようなエラーが出る。
1
2
3
4
5
6
7
8
Python 3.10.12 (main, Jul 3 2023, 14:40:47) [GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import mediapipe as mp
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/python3.10/lib/python3.10/site-packages/mediapipe/__init__.py", line 30, in <module>
import mediapipe.tasks.python as tasks
ImportError: cannot import name 'python' from 'mediapipe.tasks.python' (/usr/python3.10/lib/python3.10/site-packages/mediapipe/tasks/python/__init__.py)
これは、ソースのmediapipe/__init__.py
を動的に変更するビルドスクリプトにバグがあるらしく、
下記のように何度も再定義されるようになってしまっている。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# Copyright 2019 - 2022 The MediaPipe Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from mediapipe.python import *
import mediapipe.python.solutions as solutions
import mediapipe.tasks.python as tasks
del framework
del gpu
del modules
del python
del mediapipe
del util
__version__ = 'dev'
from mediapipe.python import *
import mediapipe.python.solutions as solutions
import mediapipe.tasks.python as tasks
del framework
del gpu
del modules
del python
del mediapipe
del util
__version__ = 'dev'
...
どうやらsetup.py
の_add_mp_init_files()
があやしい。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def _add_mp_init_files():
"""Add __init__.py to mediapipe root directories to make the subdirectories indexable."""
open(MP_ROOT_INIT_PY, 'w').close()
# Save the original mediapipe/__init__.py file.
shutil.copyfile(MP_DIR_INIT_PY, _get_backup_file(MP_DIR_INIT_PY))
mp_dir_init_file = open(MP_DIR_INIT_PY, 'a')
mp_dir_init_file.writelines([
'\n', 'from mediapipe.python import *\n',
'import mediapipe.python.solutions as solutions \n',
'import mediapipe.tasks.python as tasks\n', '\n\n', 'del framework\n',
'del gpu\n', 'del modules\n', 'del python\n', 'del mediapipe\n',
'del util\n', '__version__ = \'{}\''.format(__version__), '\n'
])
mp_dir_init_file.close()
- BuildPyの
run()
で_add_mp_init_files()
が呼ばれ、mediapipe/__init__.py
のバックアップを用意した上で編集される - BuildPyの
run()
内の他のビルド作業を実行 - ビルドが終了したらRestoreの
run()
で編集されたmediapipe/__init__.py
を消去した上で、バックアップを元に戻す
と処理しているようだが、当然2のビルド中に失敗したり強制中断したりすることもあるわけで、 それが残ったまま異常終了してしまっているのが原因の模様。
更新履歴
- 2021-12-19: 初期バージョン。
- 2023-04-24: 22.04で検証。
- 2023-06-21: mediapipe-0.10.1で検証。
- 2023-07-04: ビルド時・ビルド後の不具合について追記。
- 2023-07-05: Raspberry Pi OS用バイナリを追加