LoginSignup
11
6

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-01-08

Lambda Layers

AWS Lambdaのデプロイパッケージには50MBのサイズ制限がある。Numpy・SciPy・OpenCVをベタにビルドすると、それだけでお腹いっぱい。
そこでLambda Layers。展開後のサイズで250MBまで使える。
AWS公式は現在Numpy・SciPyのみ提供している。OpenCVも当然あっていいはずなのに今はまだないので、丸1日かけてビルドした。

追記

展開後250MB制限がつらいので、節約術(strip -s)を使った。70MBほど減っている。

準備

要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

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 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

RUN mkdir ~/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 ~/foo/python
RUN mv ~/bar_dist/lib ~/foo/python/
WORKDIR $HOME/foo
RUN find . -name *.so|xargs -n 1 strip -s
CMD zip -ry9 ~/cv2_layer.zip * && cp ~/cv2_layer.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

11
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
6