Lambda レイヤーにライブラリを追加する ( OpenCV 編)
概要
Lambda の Python ランタイムから OpenCV モジュールを利用できるようにするため、Lambda レイヤーに OpenCV を追加します。
構築環境
$ python -V
Python 3.9.12
$ pip -V
pip 22.0.4 from /home/ec2-user/.anyenv/envs/pyenv/versions/3.9.12/lib/python3.9/site-packages/pip (python 3.9)
Lambda レイヤーに OpenCV モジュールを追加する手順
作業用ディレクトリとレイヤーパスの作成
mkdir -p ~/opencv_layer/python
OpenCV (opencv-python) のインストール
python
ディレクトリに opencv-python
をインストールします。
$ cd ~/opencv_layer
$ pip install opencv-python -t python
Collecting opencv-python
Using cached opencv_python-4.5.5.64-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (60.5 MB)
Collecting numpy>=1.17.3
Using cached numpy-1.22.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (16.8 MB)
Installing collected packages: numpy, opencv-python
Successfully installed numpy-1.22.3 opencv-python-4.5.5.64
mesa-libGL のインストール
現状、opencv-python
をインストールしたディレクトリをプロイパッケージ化 (zip ファイルアーカイブ) して、Lambda レイヤーを作成して cv2
を import
すると以下のようなエラーが発生します。
[ERROR] Runtime.ImportModuleError: Unable to import module 'lambda_function': libGL.so.1: cannot open shared object file: No such file or directory
既知の問題みたいで以下のサイトを参考に対応していきます。
まず、mesa-libGL
をインストールします。
sudo yum install -y mesa-libGL
mesa-libGL
をインストール後に、必要なライブラリを python
ディレクトリに追加します。
cd ~/opencv_layer
cp -v /usr/lib64/libGL.so.1 ./python/opencv_python.libs/
cp -v /usr/lib64/libgthread-2.0.so.0 ./python/opencv_python.libs/
cp -v /usr/lib64/libglib-2.0.so.0 ./python/opencv_python.libs/
cp -v /usr/lib64/libGLX.so.0 ./python/opencv_python.libs/
cp -v /usr/lib64/libX11.so.6 ./python/opencv_python.libs/
cp -v /usr/lib64/libXext.so.6 ./python/opencv_python.libs/
cp -v /usr/lib64/libGLdispatch.so.0 ./python/opencv_python.libs/
cp -v /usr/lib64/libGLX_mesa.so.0.0.0 ./python/opencv_python.libs/
cp -v /usr/lib64/libxcb.so.1 ./python/opencv_python.libs/
cp -v /usr/lib64/libXau.so.6 ./python/opencv_python.libs/
cp -v /lib64/libGLdispatch.so.0.0.0 ./python/opencv_python.libs/
軽量化のために不要なファイルを削除する
そのままだと、236 MB もあるので不要なファイルを削除して少しでも軽くします。
$ du -sh python/
236M python/
Serverless Framework
の [Slim Package]1 を参考に dist-info
、__pycache__
、pyc
、pyo
を削除します。
find ./python -type d -regextype posix-basic -regex ".*dist-info.*" | xargs rm -rf
find ./python -type d -regextype posix-basic -regex ".*__pycache__.*" | xargs rm -rf
find ./python -type f -regextype posix-basic -regex ".*\.py[c|o]" | xargs rm -rf
8 MB だけ軽くなりました。。。
$ du -sh python/
228M python/
デプロイパッケージ化 (zip ファイルアーカイブ)
cd ~/opencv_layer
zip -r9 opencv_layer.zip python
不要なファイルを削除して軽量化する
Lambda レイヤーの作成
デプロイパッケージを使用した Lambda レイヤーの作成手順はこちらにまとめてあります。
動作確認
作成した Lambda レイヤーを使用する Lambda 関数を作成し、テスト実行してみます。
特にエラーが発生せず、実行結果のログに cv2
モジュール内で定義されている関数、属性などの一覧が表示されていれば成功です。
import cv2
def lambda_handler(event, context):
print(dir(cv2))
Lambda レイヤーに ライブラリを追加する ( OpenCV 編) まとめ
opencv-python
をインストールしただけでも 236 MB にもなります。
2022/04 時点では、Lambda デプロイパッケージ (zip ファイルアーカイブ) の上限サイズは 250 MB (解凍後)2 です。
かなりギリギリで、opencv-python
以外のモジュールを追加するのも難しいです。
opencv-contrib-python
なんて入りません。
どうしても Lambda で opencv
を使用する場合は、コードパッケージサイズの上限が 10 GB2 もあるコンテナイメージを使用することを検討した方良いかなと思います。
Footnotes
個人開発したサービス
個人開発したサービス