AWSをいじり倒す(13.lambda)
食わず嫌いしてたlambdaを使ってみる。
今回は目的があって、
s3にファイルが入ったタイミングで
tensorflowで作成したモデルを使って推論をするプログラムを動かしたい、というもの。
まずは下調べしてみたけど、やっぱりちょっとめんどくさい。
今回は手元にあるpythonのコードを動かすのが目的なんだけど、
import numpyとかpandasとかしてたら、
事前にそれらパッケージをzipでアップロードしてあげないといけないようだ
pandasをLambdaのLayerとして追加する - Qiita
そのパッケージも、ローカルで作ってもだめで、指定したEC2で作る必要がある
まず最初にややこしいのが、使うpythonのバージョンによって
アップロードするパッケージの生成元となるEC2のAMIを選ばないといけない点
今回使おうとしているpython3.7のOSはAmazon Linux(2ではない)
のでこのAMIを選んでインスタンスを起動。
次に、EC2のデフォルトpythonのバージョンが2.7だかなんだかで古いので
目的のバージョンのpythonをインストール。
現時点でyumに対応したpythonは3.6系までしかないので、
3.7以降はソースからインストールするしかない
今回はPython3.7.6を使う。
具体的な手順はここが参考になった
AWS Lambdaでpandasを利用する(Lambda Layers編) - marmarossa’s blog
まず目的のpythonをダウンロード
curl https://www.python.org/ftp/python/3.7.6/Python-3.7.6.tgz -o Python-3.7.6.tgz
解凍
tar xzf Python-3.7.6.tgz
ディレクトリに移動
cd Python-3.7.6
必須ライブラリをインストール
yum install gcc openssl-devel bzip2-devel libffi-devel
コンパイルしてインストール
./configure --enable-optimizations
sudo make altinstall
パッケージをインストールするディレクトリを作成
mkdir python/lib/python3.7/site-packages/
pandasのインストール
pip3.7 install pandas -t ./python/lib/python3.7/site-packages/
kerasのインストール
pip3.7 install keras -t ./python/lib/python3.7/site-packages/
zipに固める
zip pandaskeras.zip python/ -r
S3にアップロード(EC2へのS3アクセス権限付与など忘れずに)
aws s3 mv pandaskeras.zip s3://[s3bucket名]/module/pandaskeras.zip
S3のコンソール画面からアップロードされたことを確認して、
オブジェクトURLをメモっておく
lambdaの画面に移動
Additional Resourcesからレイヤーを選択、レイヤーの作成
レイヤーの作成。
S3からアップロードを選択し
リンクURLに先ほどメモしたURLを貼る
互換性のあるランタイムオプションはPython3.7を選択
次に関数の作成
まずはHello Worldから。
ロールは特に用意していないので作ってもらう
関数の作成を実行。
ほどなくして作成が完了
何かいろいろできそう(小並感)
ともあれ関数を実行してみる。
右上のテストボタンを押す
こんな画面が出てくるので、イベント名に適当にhelloと入力、作成
再度テストを実行
結果がずらずらとでてきた。とりあえずは動いたようだ。
さて、問題のimport pandasができるのかを試す
レイヤーを選択
お客様のレイヤーにさっき登録したレイヤーが出てきた。
numpyとscipyならデフォルトで用意してくれとるのね。
ちなみに、余談だが試行錯誤してるときはこんな怒られ方をした
どうも、追加パッケージは合計262MBまでしかだめらしい。
AWS LambdaでTensorFlow 2.0を使った画像分類 - ユニファ開発者ブログ
この辺にいかにやりくりするか、みたいなテクニックが書いてあった。
ええ、そこって気を使わないかんとこなの・・・。
いろんなものimportして大きめのプログラム動かそうと思ったらlambdaは諦めて
EC2で普通に動かすしかないのかも。
とりあえず追加は完了。
プログラムにimport pandasとかを追加してテストしてみる。
ソースを変更したら、Saveしたのちにテストを実行
どうやらうまくいったらしい。
import kerasも試してみる
ぐえ、tensorflowもいりますよ、と(凡ミス)。
しかしtensorflowは馬鹿デカ容量なので
上に書いたように262MBなんて余裕で超えて、そのままlambdaには持ってこれない。
一応EC2にインストールしてみる
pip3.7 install tensorflow -t ./python/lib/python3.7/site-packages/ --no-cache-dir
(--no-cache-dirについては以下)
AWS EC2でMemoryErrorとNo space left on deviceで詰まった話 - Qiita
ずらずら、とインストールされた中からダメ元で重そうなのを消してみる。
tensorboardとかは確かにいらんよなぁ
容量を確認するコマンドを打ってみる
du -sh ./*/
本体が1.5GB〜!!
犯人探ししていこう
これか。
これ消しちゃまずそうなやつ・・・え、みんなどうやってんの?
Running TensorFlow on AWS Lambda using Serverless - Mike Moritz - Medium
slim
— Removes unneeded files and directories such as *.so
, *.pyc
, dist-info
, etc.
まじ?これ消していいの?(わかってない
どうみてもプログラムの本体だから無理だよなぁ
物は試しってことで除外してzipしてみる
[ec2-user@ip-172-31-14-167 ~]$ zip pkt.zip python/ -r -x python/lib/python3.7/site-packages/tensorflow/python/_pywrap_tensorflow_internal.so
できたのは164MBのzip
レイヤーに登録しようとすると
これでもでかすぎてだめか。
tensorflowさえ使わなければ万事うまくいきそうなんだけど、
使うんだよな〜〜
次回、どうも成功してる事例っぽいserverlessからデプロイするやり方をダメ元で試してみる・・・。
あと、s3に格納されたファイルを引数としたり、
結果をs3に格納したりする方法を探してみると
【AWS Lambdaの基本コードその2】 S3へのファイル保存 | ナレコムAWSレシピ
これをみると普通にpythonのコードでs3にアクセスする感じなのね。
てっきり、lambdaの機能として提供されているのかと思った。
そうなってくると、あとはimportがうまくいけば
この関数のトリガーイベントの設定と、
成功時・失敗時ログをどこに流すかって設定するぐらいか。
なんだかlambdaの全体像は見えてきたが、超えるべき山がまだ高い