問題の概要
AWS Lambda(Python 3.12、x86_64アーキテクチャ)でnumpyを使用する際、Lambda Layerを構築しても以下のようなインポートエラーが発生することがあります。
[ERROR] Runtime.ImportModuleError: Unable to import module 'handler':
Error importing numpy: you should not try to import numpy from
its source directory; please exit the numpy source tree, and relaunch
your python interpreter from there.
このエラーは、numpyパッケージが正しくビルドされていない、またはLambda環境と互換性のないバイナリが含まれている場合に発生します。
原因
この問題の主な原因は以下の通りです。
- プラットフォームの不一致: ローカル環境(macOSやWindows)でpip installしたパッケージは、Lambda環境(Linux x86_64)では動作しない
- バイナリの互換性: numpyやpandasのような科学計算ライブラリは、C拡張を含むため、正しいプラットフォーム向けにコンパイルされたバイナリが必要
- 不完全なパッケージ構造: ソースファイルのみがインストールされ、コンパイル済みバイナリが含まれていない
解決方法
Dockerを使用して、Lambda環境と同じプラットフォーム向けにパッケージをビルドすることで、この問題を解決できます。
ステップバイステップの手順
以下のシェルスクリプトを使用してLambda Layerを構築します。
# 既存のファイルをクリーンアップ
rm -rf python pandas-layer.zip
# Layerのディレクトリ構造を作成
mkdir -p python
# DockerでLambda環境を使用してパッケージをインストール
docker run --rm \
-v "$PWD":/var/task \
--platform linux/amd64 \
--entrypoint pip \
public.ecr.aws/lambda/python:3.12 \
install \
--platform manylinux2014_x86_64 \
--only-binary=:all: \
--target /var/task/python \
numpy pandas
# Layer用のZIPファイルを作成
zip -r pandas-layer.zip python
コマンドの詳細説明
各オプションの意味を理解することで、他のパッケージにも応用できます。
-
--rm: コンテナ終了後に自動削除 -
-v "$PWD":/var/task: 現在のディレクトリをコンテナにマウント -
--platform linux/amd64: x86_64アーキテクチャを明示的に指定 -
--entrypoint pip: pipコマンドを直接実行 -
public.ecr.aws/lambda/python:3.12: AWS公式のLambda Python 3.12イメージを使用 -
--platform manylinux2014_x86_64: Linux x86_64用のホイールを取得 -
--only-binary=:all:: ソースからビルドせず、ビルド済みバイナリのみを使用 -
--target /var/task/python: インストール先を指定(Lambda Layerの標準パス)
Lambda Layerのアップロードと設定
- Layerをアップロード:
aws lambda publish-layer-version \
--layer-name pandas-numpy-layer \
--zip-file fileb://pandas-layer.zip \
--compatible-runtimes python3.12
-
Lambda関数にLayerをアタッチ:
- AWS Lambda コンソールで関数を開く
- 「レイヤー」セクションで「レイヤーの追加」をクリック
- カスタムレイヤーから作成したLayerを選択
-
関数コードで使用:
import numpy as np
import pandas as pd
def handler(event, context):
# numpyとpandasを正常に使用できます
arr = np.array([1, 2, 3, 4, 5])
df = pd.DataFrame({'data': arr})
return {
'statusCode': 200,
'body': f'Mean: {arr.mean()}'
}
他のパッケージへの応用
同じ方法で、他の科学計算ライブラリや複雑な依存関係を持つパッケージもインストールできます。
# scikit-learn、scipy、matplotlibなどを追加
docker run --rm \
-v "$PWD":/var/task \
--platform linux/amd64 \
--entrypoint pip \
public.ecr.aws/lambda/python:3.12 \
install \
--platform manylinux2014_x86_64 \
--only-binary=:all: \
--target /var/task/python \
numpy pandas scikit-learn scipy matplotlib
トラブルシューティングのヒント
Layerサイズの制限
Lambda Layerは解凍後50MBまで(全Layerの合計で250MB)という制限があります。大きなパッケージの場合は:
- 必要なパッケージのみをインストール
- 不要なファイル(テストファイル、ドキュメントなど)を削除
- 複数のLayerに分割
プラットフォームの確認
ARM64(Graviton)を使用している場合は、
--platform linux/arm64
と
public.ecr.aws/lambda/python:3.12-arm64
を使用してください。
まとめ
AWS Lambda環境でnumpyやpandasを使用する際は、必ずLambda環境と同じプラットフォーム向けにビルドされたパッケージを使用する必要があります。Dockerと公式のLambda Pythonイメージを使用することで、環境の違いによる問題を確実に回避できます。
この方法を使えば、複雑な科学計算ライブラリも安全にLambda環境で実行できるようになります。