【サーバレス機械学習入門】AWS Lambda レイヤーの使い方

## はじめに

これは[機械学習ツールを掘り下げる by 日経 xTECH ビジネスAI③ Advent Calendar 2019](https://qiita.com/advent-calendar/2019/machine-learning-02)の１日目の記事です。

12/20に記事を書こうと思っていたのですが１日目が埋まっていなかったので突貫工事で記事を書きました。

私はAWS Lambdaが大好きなので、Lambdaで機械学習するノウハウを書いていこうと思います。

本記事では**Lambda関数でPandasなどの外部ライブラリを使う方法**をまとめておきます。[^ase]

[^ase]: １日目がこんなんでいいのか…？

## これまでのAWS Lambda


これまでのAWS Lambdaでは、外部ライブラリを用いる場合[^built-in]

- Lambda関数のソースコード
- ライブラリのソースコード

これらをZipファイル（デプロイパッケージ）にまとめてアップロードする必要がありました。

[^built-in]: [組み込み関数](https://docs.python.org/ja/3/library/functions.html)ならそのままimport可能

その結果、**関数の呼び出しは出来るがコンソール上で編集が出来ない**という何とも不便な状況でした。

![Screenshot_2019-12-03 Lambda Management Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166931/bd1fa707-8ca3-aaf2-3eef-fe4f5050ace7.png)



これを解決するのが[AWS Lambda レイヤー](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-layers.html)です。


## AWS Lambda Layersとは

>追加のコードとコンテンツをレイヤーの形式で取り込むように Lambda 関数を設定することができます。レイヤーは、ライブラリ、カスタムランタイム、またはその他の依存関係を含む ZIP アーカイブです。レイヤーを使用することで、関数のライブラリを使用することができます。デプロイパッケージに含める必要はありません。

直訳日本語が難しいので端的にまとめると。**”外部ライブラリや自作モジュールなどをレイヤー形式で取り込むことが出来る機能”**のことです。

ライブラリの使い回しやコンソール上での編集が可能になります。

![FireShot Capture 015 - Lambda Management Console - console.aws.amazon.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166931/753b187c-78c1-5d0d-d1aa-1d2099694f02.png)


## Getting Started

- Cloud9の設定
- Python環境構築
- ZIPアーカイブの作成
- Layerの作成

### Cloud9のセッティング

ここではLambdaLayersの開発環境としてCloud9を使います。

>コードを記述、実行、デバッグできるクラウドベースの統合開発環境 (IDE)
[AWS Cloud9（Cloud IDE でコードを記述、実行、デバッグ）| AWS](https://aws.amazon.com/jp/cloud9/)


![Screenshot_2019-12-03 Welcome to AWS Cloud9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166931/74621feb-5151-f8e9-27aa-b3655bc3ab4f.png)

環境構築はデフォルト設定のままで大丈夫です。

>①環境名と説明書きを入力
>![Screenshot_2019-12-03 Create a new environment.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166931/0f2d237a-3cf3-f568-bc0f-10bbdb5cfc48.png)
>②インスタンスタイプやOSなどの設定
>![あScreenshot_2019-12-03 Create a new environment.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166931/15a242b5-84fa-f5f9-adf2-4635f7d8214e.png)
>③あとは作成するだけ
>![iScreenshot_2019-12-03 Create a new environment.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166931/691c06a7-fd32-ee8e-7ba6-dc701f29f24a.png)
>うまくいけば下記のようなIDEが使えるようになります。
>![FireShot Capture 005 - lambda-development - AWS Cloud9 - ap-northeast-1.console.aws.amazon.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166931/46a01d80-54e2-7425-6ee5-5894106aec27.png)


### Python環境構築

ここでは複数バージョンのPythonを扱えるようにしたいので[pyenv](https://github.com/pyenv/pyenv)のインストールとPython3.8のインストールを行います。

[[Python] pyenvを使ってPythonの複数のバージョンを使い分ける - YoheiM .NET](https://www.yoheim.net/blog.php?q=20170204)




```shell-session
# pyenvのインストール
curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash
# 環境変数の設定
vi ~/.bashrc
```


`.bashrc`のファイルの末尾に下記を追記する

```
export PATH="/home/ec2-user/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
```

`.bashrc`を再読み込み

```shell-session
source ~/.bash_profile
```

pythonのバージョン変更

ここでは3.8.0に変更してみます。

```shell-session
# python3.8をインストール
pyenv install 3.8.0
# python3.8を設定
pyenv global 3.8.0
```

インストールされているか確認します。

```shell-session
# pyenvでインストール済みのバージョン確認
pyenv versions

# 現在のpythonバージョン
python3 -V

```

`python -V`で確認すると3.6.8になっているので注意。

### Zipアーカイブ作成

```shell-session
mkdir layer_pandas && cd $_
mkdir python && cd $_
pip3 install -t ./ pandas
cd ../
zip -r layer_pandas.zip python/
```

`pip install`ではなく`pip3 install`を使うこと！

![FireShot Capture 006 - lambda-development - AWS Cloud9 - ap-northeast-1.console.aws.amazon.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166931/681ec279-5ac0-43ed-6dce-d8ec835cedee.png)


完成したlayer_pandas.zipをダウンロードもしくはS3にアップロードしておきます。

### Layerの作成

Lambdaのコンソール画面の左のカラムの最下部にLayerという項目があるので、下記のように設定&アップロード。

![FireShot Capture 008 - Lambda Management Console - console.aws.amazon.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166931/98164915-a59a-b6c5-1416-bd2a39a15a93.png)


しばらく待つとレイヤーが作成されます。

![FireShot Capture 009 - Lambda Management Console - console.aws.amazon.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166931/51cc1c2f-1033-f2fe-56b2-53092f8c9b09.png)




## 実験

少しわかりにくいですが、画面中央のLayersの部分をクリックすると設定可能です。
![FireShot Capture 010 - Lambda Management Console - console.aws.amazon.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166931/ac787e83-23f5-6426-f663-0f8a3d7dbd5c.png)


PandasはNumpy同梱なので`np.xxxxx`も使えるようになります。

![FireShot Capture 014 - Lambda Management Console - console.aws.amazon.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166931/b575937a-8dac-b905-eb5e-bd82d01293b1.png)


## まとめ

LambdaLayersを使えばLambda開発がぐっとラクになります。

特にwebデータの収集用のレイヤーを用意すると使い回しが効くのでオススメです。

```shell-session
mkdir layer_scraping && cd $_
mkdir python && cd $_
pip3 install -t ./ beautifulsoup4
pip3 install -t ./ requests
pip3 install -t ./ pandas
cd ../
zip -r layer_scraping.zip python/
```

## おわりに

とりあえず、Getting Startedな内容ですがLambdaで機械学習する準備が整いました。次はLightGBMやTensorflowなどの機械学習フレームワークが動かせるか検証したいと思います。


現場からは以上です。