どうもこんにちは。
今回は、AWS Lambdaを使用してPillowをインポートしようとした時につまづいたのでメモしておきます。
Pillowってなに?
そもそもPillowって何って話ですが、以下の記事にはこのように記載されていました。
OpenCVのようにコンピュータービジョン系の高度な画像処理(顔検出やオプティカルフローなど)はできないが、リサイズ(拡大・縮小)や回転、トリミング(部分切り出し)のような単純な処理が簡単にできる。
ほうほう...
今回は、base64エンコードされた画像データをバイナリデータに変換し、さらにバイナリデータから画像を読み込んで画像オブジェクトに変換してS3に保存するというなんともめんどくさい処理をする必要があるので、Pillowを使用しています。
# 画像生成試してます
response = bedrock_runtime.invoke_model(
body=body,
modelId="amazon.titan-image-generator-v2",
accept="application/json",
contentType="application/json"
)
response_body = json.loads(response['body'].read())
# ここやで
images = [Image.open(BytesIO(base64.b64decode(base64_image))) for base64_image in response_body.get("images")]
早速、LambdaでPillowをインポートしてみる
from PIL import Image
これを実行すると...
[ERROR] Runtime.ImportModuleError: Unable to import module 'lambda_function': No module named 'PIL'
Traceback (most recent call last):
やめてぇ...ってなるわけですよね。
よし、Lambda Layer使いましょ。
Lambda Layerを知らない人向けに...
Lambda Layerは、Lambdaにデフォルトでインストールされていないライブラリを使用したい時に使用します。
例えば、Pythonでよく使用するpandas
などは、Lambdaでデフォルトインストールされていないので、ローカルPCにダウンロードして、Zip圧縮して、Lambda Layerに登録して、インポートという流れを踏む必要があります。
使い方さえわかれば簡単でっす。
ローカルにダウンロード
mkdir pillow
cd pillow
pip install \
--platform manylinux2014_x86_64 \
--target=python \
--implementation cp \
--python-version 3.12 \
--only-binary=:all: \
--upgrade Pillow
--platform
については、今後のバージョンアップで変更になる気がしていますが、本記事を書いている時点(2024年8月)ではmanylinux2014_x86_64
で問題ないです。
これでローカルにダウンロードはできました。
Zip圧縮
pip install
を実行すると、pillow
ディレクトリにpython
ディレクトリが作成されていると思います。
(上のコマンドで--target=python
を指定したからです。)
% ls
python
このpython
ディレクトリの中にPillow
ライブラリが入っています。
というわけで、python
ディレクトリをZip圧縮します。
zip -r9 layer.zip python
layer.zip
のところは、自分の好きなファイル名にしていただいてOKです。
これで、Zip圧縮完了です。
Lambda Layerにアップロード
AWSコンソールのレイヤーから新しくZipをアップロードします。
Lambda関数でレイヤーを追加
最後に、Lambda関数が登録したレイヤーを参照できるように、レイヤーの追加をしてください。
これで、以下のようなエラーとはおさらばです。
[ERROR] Runtime.ImportModuleError: Unable to import module 'lambda_function': No module named 'PIL'
Traceback (most recent call last):