【AWS Lambda】250MB制限を乗り越えてPyTorchを導入する方法

【AWS Lambda】250MB制限を乗り越えてPyTorchを導入する方法

こんにちは、自動化・AIツール開発担当の中田(@valmore_nakata)です。

「 Unzipped size must be smaller than 262144000 bytes 」
AWS Lambdaを扱っていてこのエラーに苦しめられた人は多いのではないでしょうか?
デプロイする際のパッケージサイズが250MBを超えた際に出るエラーです。

250MBもあれば十分と思われるかもしれませんが、パッケージを含めるとなると話は別で、結構すぐに超えてしまいます。
機械学習などでよく利用されるPyTorchも250MBを超えるので通常の方法ではlambdaへデプロイすることはできません。

しかし2020年6月、EFS(Elastic File System)をlambda関数で利用できるようになり、状況は一変しました。EFSを使えば250MB制限は乗り越えられるのです。

そこで本記事では、EFSを利用してPyTorchを使ったlambda関数をデプロイする手順をご紹介します。 PyTorch以外のライブラリでも基本的な手順は変わりません。
手順は多いですが、一つ一つ順に説明していきます。AWS Lambdaユーザーにとって驚くほど便利なソリューションなので、是非試してみてください。

EFSでファイルシステムを作成

まずはEFSでファイルシステムを作成しましょう。
AWSコンソールでEFSを選択し、「ファイルシステムの作成」ボタンをクリック。名前とVPCを入力して作成します。
ここでは、デフォルトのVPCを選択しました。

続いて作成したファイルシステムのネットワーク設定を行います。作成したファイルシステムのネットワーク項目を選択し、「管理」ボタンをクリックしてください。

各アベイラビリティーゾーンのセキュリティグループを選択します。2049番ポートからのアクセスを開放しているセキュリティグループを設定し、保存してください。

EC2でEFSへPyTorchをインストール

EFSをマウントしPyTorchをインストールするために、EC2インスタンスを立ち上げます。
OSはAmazon Linuxを選択してください。インスタンスタイプはnanoやmicroだと小さすぎるかもしれません。記事ではt3a.smallを選びました。
立ち上げるEC2インスタンスは、EFSのファイルシステムと同じVPCを選択する必要があることに注意しましょう。

立ち上げたEC2にsshで接続し、作成したEFSのファイルシステムをマウントします。
{ファイルシステムID}を作成したファイルシステムのIDに置き換えて、以下のコマンドを実行してください。

sudo yum update
sudo yum install -y amazon-efs-utils
sudo mkdir /mnt/efs
sudo mount -t efs {ファイルシステムID}:/ /mnt/efs
df -Th

上記のように、/mnt/efsでマウントができていれば成功です。
マウントしたディレクトリの所有者をec2-userに変更しておきましょう。

sudo chown ec2-user:ec2-user /mnt/efs

続いてlambdaのランタイムがpython3系なので、python3をインストールします。以下のコマンドを実行してください。

sudo yum install -y python3
python3 -V

python3のインストールが完了しました(記事ではpython3.7.9)。
最後にマウント先のファイルシステムにpytorchをインストールします。インストールに使用するURLはこちらから確認してください。 https://pytorch.org/get-started/locally/
下記はインストールコマンド例です。インストール先「/mnt/efs/lib」を指定していることがポイントです。

pip3 install -t /mnt/efs/lib  torch==1.6.0+cpu torchvision==0.7.0+cpu -f https://download.pytorch.org/whl/torch_stable.html

これでefsへPyTorchのインストールが完了しました。

EFSのアクセスポイントを作成

PyTorchをインストールしたEFSにlambdaからマウントできるようにアクセスポイントを作成します。
AWSコンソールのEFSで「アクセスポイントを作成」ボタンをクリックします。

作成したファイルシステムを選択し、「アクセスポイントを作成」ボタンを押してください。

アクセスポイントの作成は以上です。

labmda関数でEFSをマウントする

いよいよlambda関数からEFSをマウントします。 まずは、lambda関数を作成しましょう。本記事ではEC2で利用したpythonが3.7.9だったので、ランタイムはpython3.7を選択しました。

続いてlambda関数がEFSにアクセスできるように、実行ロールに以下のポリシーをアタッチしてください。実行ロールは基本設定から操作できます。

  • AWSLambdaVPCAccessExecutionRole
  • AmazonElasticFileSystemClientReadWriteAccess

次にlambda関数をVPCに配置してください。
EFSのファイルシステム作成時に選択したVPCと同じものを選んでください。

これでlambdaをEFSへアタッチするための準備が整いました。lambda関数エディタ画面の下部にファイルシステムに関する項目があります。「ファイルシステムの追加」というボタンをクリックしてください。

EFSのファイルシステムのマウント設定画面が開きます。「EFSファイルシステム」、「アクセスポイント」の項目で以前作成したものを選択し、ローカルマウントパスには「/mnt/efs」と入力して保存してください。

これでlambdaからEFSが参照できるようになりました。PyTorchはEFSに存在するので、lambdaがEFS内のライブラリを参照できるように設定する必要があります。

lambda関数エディタ画面に環境変数という項目があるので、「編集」ボタンを押してください。
環境変数が設定できるので、「PYTHONPATH」をPyTorchインストール先の「/mnt/efs/lib」に設定します。

lambdaの設定は完了しました。以下のコードでPyTorchを実行できるか試してみましょう。

import torch

def lambda_handler(event, context):
    print(torch.__version__)

実行されましたでしょうか?PyTorchのバージョンがログに表示されれば成功です。タイムアウトするようであれば基本設定からタイムアウト時間を延ばしてください。
記事では1.6.0+cpuと表示されました。

まとめ

いかがでしょうか?
AWS LambdaからEFSを利用すれば様々なライブラリを使用できるようになり、できることがぐっと広がります。

ただ、lambdaをVPCに配置する必要があるのでこのままでは外部のネットワークとアクセスできなくなり弊害があるかもしれません。
S3へのアクセスが必要な場合など、以下の記事で説明していますので参考にしてみてください。
VPC設定したlambda関数からS3へアクセスする方法