opencv-pythonを並列ビルドしてビルド時間を5分の1にした
はじめに
Pythonで画像処理をする場合、pip
でインストールするopencv-python
(またはopencv-python-headless
)パッケージを使うことが多いかと思います。
opencv-python
パッケージにはOpenCVのビルド済みバイナリが含まれているため、別途OpenCVをインストールする必要もなく、簡単にOpenCVを使うことができます。
ただ、opencv-python
パッケージに含まれているビルド済みバイナリは、ライセンスの関係でH.264に対応していないなど、H.264対応やGPU(CUDA)対応のためにopencv-python
パッケージを独自ビルドすることも少なくありません。
そのビルドにえらく時間が掛かった(約25分)ため、並列ビルドする方法を調べてみた、という話です。
結論
結論から言えばMAKEFLAGS="-j$(nproc)" python -m build --wheel
と、MAKEFLAGS="-j$(nproc)"
を付加するだけで並列ビルドされました。
以下に示す具体例の場合、これだけでビルド時間が約25分から約5分へ、5分の1になりました。もちろんビルド時間、短縮の度合いは環境依存です。
このコマンドはopencv-python
パッケージに限らず、適切に依存関係が書かれたMakefile
があり、make
コマンドを使っているパッケージに適用できます。(CMakeを使ってMakefile
を生成している場合も含む)
なお、$(nproc)
の部分は実行するマシンのCPUコア数になるため、16コアマシンではMAKEFLAGS="-j16"
として展開されます。
ここではすべてのCPUコアを使用してビルドすることを想定していますが、一部のCPUコアだけを使いたい場合は適宜調整してください。
MAKEFLAGS
の他にもCMAKE_ARGS
、CMAKE_MAKE_PROGRAM
、CMAKE_BUILD_PARALLEL_LEVEL
なども使ってみましたがビルドエラーとなり、問題を解決することはできませんでした。
opencv-python-headless
パッケージをビルドする
具体例: H.264対応の具体例として、H.264対応のopencv-python-headless
パッケージ(バージョン4.10.0.84
)をビルドする例を示します。
今回はpython:3.11-slim
イメージを使い、Dockerコンテナ上でビルドしました。
なお、headless
版はGUI関係を含まないため、依存関係が少なく、ビルドされたパッケージも小さくなります。
docker run -it --rm python:3.11-slim bash
# 必要なDebianパッケージをインストールする
apt update
apt install --yes --no-install-recommends build-essential cmake libavcodec-dev libavformat-dev libturbojpeg0-dev libopencv-dev libopenexr-dev libpng-dev libssl-dev libswscale-dev libtiff-dev libwebp-dev libx264-dev
# 必要なPythonパッケージをインストールする
python -m pip install build==1.2.2.post1 packaging==24.2 pyproject_hooks==1.2.0
# opencv-python-headlessパッケージをソースからビルドする
mkdir /tmp/opencv
cd /tmp/opencv/
python -m pip download --no-binary opencv-python-headless opencv-python-headless==4.10.0.84
tar zxfv opencv-python-headless-4.10.0.84.tar.gz
cd opencv-python-headless-4.10.0.84/
MAKEFLAGS="-j$(nproc)" python -m build --wheel
# ビルドしたopencv-python-headlessパッケージをインストールする
python -m pip install dist/opencv_python_headless-4.10.0.84-cp311-cp311-linux_x86_64.whl
おわりに
Pythonパッケージの並列ビルドについて調べる中で、以下のコマンド、環境変数を初めて使いました。
-
python -m pip download
コマンド -
python -m build --wheel
コマンド -
MAKEFLAGS
環境変数
いかんせん初めて使ったので誤りなどがあるかもしれません。その時は優しく教えて頂けると幸いです。
Discussion