AWS LambdaのLayer用にOpenCVをビルド(Python3)

AWS LambdaのLayer用にOpenCVをビルド(Python3):


Lambda Layers

AWS Lambdaのデプロイパッケージには50MBのサイズ制限がある。Numpy・SciPy・OpenCVをベタにビルドすると、それだけでお腹いっぱい。

そこでLambda Layers。展開後のサイズで250MBまで使える。

AWS公式は現在Numpy・SciPyのみ提供している。OpenCVも当然あっていいはずなのに今はまだないので、丸1日かけてビルドした。


準備

要Docker。

使うOpenCVのバージョンを決める。決めたら、ソースツリーをzipで固める。ファイル名はopencv-master.zipとopencv_contrib-master.zip。もしHEADでよければ、GitHubでDownload ZIPしたそのまんま。


ビルド

以下のDockerfileとdocker-compose.ymlと同じところに、opencv-master.zipとopencv_contrib-master.zipを置いておく。

Dockerfile
FROM lambci/lambda:build-python3.6 
ENV AWS_DEFAULT_REGION ap-northeast-1 
 
RUN yum update -y 
RUN sed -i -e 's/enabled=0/enabled=1/' /etc/yum.repos.d/epel.repo 
RUN yum install cmake3 -y 
RUN pip install --upgrade pip 
RUN pip install numpy 
 
ENV HOME /home/hoge 
RUN mkdir $HOME 
WORKDIR $HOME 
 
COPY opencv-master.zip . 
RUN unzip opencv-master.zip 
RUN mv opencv-master opencv 
COPY opencv_contrib-master.zip . 
RUN unzip opencv_contrib-master.zip 
RUN mv opencv_contrib-master opencv_contrib 
 
RUN mkdir $HOME/opencv/build 
WORKDIR $HOME/opencv/build 
RUN cmake3 -D CMAKE_BUILD_TYPE=RELEASE -D BUILD_SHARED_LIBS=NO \ 
    -D BUILD_LIST=aruco,features2d,imgcodecs,imgproc,python3,xfeatures2d \ 
    -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \ 
    -D PYTHON3_EXECUTABLE=/var/lang/bin/python \ 
    -D CMAKE_INSTALL_PREFIX=~/bar_dist .. 
RUN make install 
 
RUN mkdir -p $HOME/foo/python 
RUN mv $HOME/bar_dist/lib $HOME/foo/python/ 
WORKDIR $HOME/foo 
CMD zip -ry9 ~/cv2_ll.zip * && cp ~/cv2_ll.zip /share 
docker-compose.yml
version: '2' 
services: 
  app: 
    build: 
      context: . 
    volumes: 
      - .:/share 
上記のDockerfileなどなどを置いたディレクトリで、

docker-compose build 
docker-compose up 
カレントディレクトリにcv2_ll.zipが生成される。


使い方

cv2_ll.zipをAWSコンソールでLayerとして登録する。自分のLambda FunctionにこのLayerをつける。このとき、AWS公式で提供されているNumpy・SciPyのLayerも同時につける必要がある。

importに時間がかかるので、ハンドラモジュールのグローバルでimportする必要がある。ハンドラ関数内でimport cv2しようとすると、デフォルトの制限時間の3秒以内に終わらない。


OpenCVモジュールの取捨選択

BUILD_LISTを編集する。ちなみに上のリストでビルドすると、2019/01/08のHEADで展開後サイズが49,254,022バイトとなる。


共有ライブラリ?

上の例では静的リンクしてあるので、メモリを余計に食っているはず。Lambda FunctionでLD_LIBRARY_PATHを見ると/opt/libに通っているので(Layerは/optに展開される仕組み)、もしここに.soを配置すれば使えるはず。

追記:

むしろメモリを余計に食った。import cv2しただけの状態で54MB vs 58MB。


参考

AWS Lambda で OpenCV と Pillow を使う環境を準備する
Using Packages and Native nodejs Modules in AWS Lambda

コメント

このブログの人気の投稿

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2020-12-01 09:41:49 RSSフィード2020-12-01 09:00 分まとめ(69件)