AWS Lambda
機能を使用してビデオを生成したいと思います。
そして今、私のLambda
関数を構築する次のプロセスがあります:
Amazon Linux EC2
インスタンスを起動し、これをルートとして実行します:
#! /usr/bin/env bash
# Install the SciPy stack on Amazon Linux and prepare it for AWS Lambda
yum -y update
yum -y groupinstall "Development Tools"
yum -y install blas --enablerepo=epel
yum -y install lapack --enablerepo=epel
yum -y install atlas-sse3-devel --enablerepo=epel
yum -y install Cython --enablerepo=epel
yum -y install python27
yum -y install python27-numpy.x86_64
yum -y install python27-numpy-f2py.x86_64
yum -y install python27-scipy.x86_64
/usr/local/bin/pip install --upgrade pip
mkdir -p /home/ec2-user/stack
/usr/local/bin/pip install moviepy -t /home/ec2-user/stack
cp -R /usr/lib64/python2.7/dist-packages/numpy /home/ec2-user/stack/numpy
cp -R /usr/lib64/python2.7/dist-packages/scipy /home/ec2-user/stack/scipy
tar -czvf stack.tgz /home/ec2-user/stack/*
結果のtarballをラップトップにコピーします。次に、このスクリプトを実行してZipアーカイブを構築します。
#! /usr/bin/env bash
mkdir tmp
rm lambda.Zip
tar -xzf stack.tgz -C tmp
Zip -9 lambda.Zip process_movie.py
Zip -r9 lambda.Zip *.ttf
cd tmp/home/ec2-user/stack/
Zip -r9 ../../../../lambda.Zip *
process_movie.py
スクリプトは、現時点ではスタックが正常であるかどうかを確認するためのテストにすぎません。
def make_movie(event, context):
import os
print(os.listdir('.'))
print(os.listdir('numpy'))
try:
import scipy
except ImportError:
print('can not import scipy')
try:
import numpy
except ImportError:
print('can not import numpy')
try:
import moviepy
except ImportError:
print('can not import moviepy')
次に、結果のアーカイブをS3にアップロードして、lambda
関数のソースにします。関数をテストすると、次のcallstack
が得られます。
START RequestId: 36c62b93-b94f-11e5-9da7-83f24fc4b7ca Version: $LATEST
['tqdm', 'imageio-1.4.Egg-info', 'decorator.pyc', 'process_movie.py', 'decorator-4.0.6.dist-info', 'imageio', 'moviepy', 'tqdm-3.4.0.dist-info', 'scipy', 'numpy', 'OpenSans-Regular.ttf', 'decorator.py', 'moviepy-0.2.2.11.Egg-info']
['add_newdocs.pyo', 'numarray', '__init__.py', '__config__.pyc', '_import_tools.py', 'setup.pyo', '_import_tools.pyc', 'doc', 'setupscons.py', '__init__.pyc', 'setup.py', 'version.py', 'add_newdocs.py', 'random', 'dual.pyo', 'version.pyo', 'ctypeslib.pyc', 'version.pyc', 'testing', 'dual.pyc', 'polynomial', '__config__.pyo', 'f2py', 'core', 'linalg', 'distutils', 'matlib.pyo', 'tests', 'matlib.pyc', 'setupscons.pyc', 'setup.pyc', 'ctypeslib.py', 'numpy', '__config__.py', 'matrixlib', 'dual.py', 'lib', 'ma', '_import_tools.pyo', 'ctypeslib.pyo', 'add_newdocs.pyc', 'fft', 'matlib.py', 'setupscons.pyo', '__init__.pyo', 'oldnumeric', 'compat']
can not import scipy
'module' object has no attribute 'core': AttributeError
Traceback (most recent call last):
File "/var/task/process_movie.py", line 91, in make_movie
import numpy
File "/var/task/numpy/__init__.py", line 122, in <module>
from numpy.__config__ import show as show_config
File "/var/task/numpy/numpy/__init__.py", line 137, in <module>
import add_newdocs
File "/var/task/numpy/numpy/add_newdocs.py", line 9, in <module>
from numpy.lib import add_newdoc
File "/var/task/numpy/lib/__init__.py", line 13, in <module>
from polynomial import *
File "/var/task/numpy/lib/polynomial.py", line 11, in <module>
import numpy.core.numeric as NX
AttributeError: 'module' object has no attribute 'core'
END RequestId: 36c62b93-b94f-11e5-9da7-83f24fc4b7ca
REPORT RequestId: 36c62b93-b94f-11e5-9da7-83f24fc4b7ca Duration: 112.49 ms Billed Duration: 200 ms Memory Size: 1536 MB Max Memory Used: 14 MB
pythonがフォルダー構造に存在するコアディレクトリを見つけられない理由を理解できません。
編集:
@jarmodのアドバイスに従って、lambda
functionを次のように減らしました。
def make_movie(event, context):
print('running make movie')
import numpy
次のエラーが発生しました。
START RequestId: 6abd7ef6-b9de-11e5-8aee-918ac0a06113 Version: $LATEST
running make movie
Error importing numpy: you should not try to import numpy from
its source directory; please exit the numpy source tree, and relaunch
your python intepreter from there.: ImportError
Traceback (most recent call last):
File "/var/task/process_movie.py", line 3, in make_movie
import numpy
File "/var/task/numpy/__init__.py", line 127, in <module>
raise ImportError(msg)
ImportError: Error importing numpy: you should not try to import numpy from
its source directory; please exit the numpy source tree, and relaunch
your python intepreter from there.
END RequestId: 6abd7ef6-b9de-11e5-8aee-918ac0a06113
REPORT RequestId: 6abd7ef6-b9de-11e5-8aee-918ac0a06113 Duration: 105.95 ms Billed Duration: 200 ms Memory Size: 1536 MB Max Memory Used: 14 MB
このスレッドのすべての投稿の助けを借りて、ここに記録の解決策があります:
これを機能させるには、次のことが必要です。
少なくとも2GO RAMでEC2
インスタンスを開始します(NumPy
およびSciPy
をコンパイルできるようにするため)
必要な依存関係をインストールする
Sudo yum -y update
Sudo yum -y upgrade
Sudo yum -y groupinstall "Development Tools"
Sudo yum -y install blas --enablerepo=epel
Sudo yum -y install lapack --enablerepo=epel
Sudo yum -y install Cython --enablerepo=epel
Sudo yum install python27-devel python27-pip gcc
virtualenv ~/env
source ~/env/bin/activate
pip install scipy
pip install numpy
pip install moviepy
stack
フォルダー内のディレクトリ(_markerlib、pip *、pkg_resources、setuptools *、easyinstall *を除く)のすべてのコンテンツをロケールマシンにコピーします。
home/ec2-user/env/lib/python2.7/dist-packages
home/ec2-user/env/lib64/python2.7/dist-packages
必要なすべての共有ライブラリをEC2
instanceから取得します。
libatlas.so.3
libf77blas.so.3
liblapack.so.3
libptf77blas.so.3
libcblas.so.3
libgfortran.so.3
libptcblas.so.3
libquadmath.so.0
それらをlib
フォルダーのstack
サブフォルダーに入れます
imageio
はmoviepy
の依存関係です。その依存関係のバイナリバージョンをダウンロードする必要があります:libfreeimage
およびffmpeg
;それらは こちら で見つけることができます。スタックフォルダーのルートに配置し、libfreeimage-3.16.0-linux64.so
からlibfreeimage.so
に名前を変更します。
これで、次を含むstack
フォルダーができました。
lib
サブフォルダー内のすべての共有ライブラリffmpeg
ルートのバイナリlibfreeimage.so
ルートでこのフォルダーを圧縮:Zip -r9 stack.Zip . -x ".*" -x "*/.*"
次のlambda_function.py
をlambda
のエントリポイントとして使用します
from __future__ import print_function
import os
import subprocess
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
LIB_DIR = os.path.join(SCRIPT_DIR, 'lib')
FFMPEG_BINARY = os.path.join(SCRIPT_DIR, 'ffmpeg')
def lambda_handler(event, context):
command = 'LD_LIBRARY_PATH={} IMAGEIO_FFMPEG_EXE={} python movie_maker.py'.format(
LIB_DIR,
FFMPEG_BINARY,
)
try:
output = subprocess.check_output(command, Shell=True)
print(output)
except subprocess.CalledProcessError as e:
print(e.output)
moviepy
、numpy
、...に依存するmovie_maker.py
scriptを記述する.
スクリプトにそれらをstack.ZipファイルZip -r9 lambda.Zip *.py
に追加します
zipをS3
にアップロードし、lambda
のソースとして使用します
stack.Zip
here をダウンロードすることもできます。
私もあなたの最初のリンクをたどっていて、numpyとpandasをインポートすることができましたこのようにLambda関数で(Windowsの場合):
使用したものと同じコマンドとAmazonの記事で推奨されているコマンドを試しました:
Sudo yum -y update
Sudo yum -y upgrade
Sudo yum -y groupinstall "Development Tools"
Sudo yum -y install blas --enablerepo=epel
Sudo yum -y install lapack --enablerepo=epel
Sudo yum -y install Cython --enablerepo=epel
Sudo yum install python27-devel python27-pip gcc
仮想環境を作成しました:
virtualenv ~/env
source ~/env/bin/activate
packagesをインストールしました:
Sudo ~/env/bin/pip2.7 install numpy
Sudo ~/env/bin/pip2.7 install pandas
その後、WinSCPを使用してログインし、/home/ec2-user/env/lib/python2.7/dist-packages
からダウンロードすべて(_markerlib、pip *、pkg_resources、setuptools *およびeasyinstall *)をダウンロードしました。 、およびEC2インスタンスの/home/ec2-user/env/lib64/python2.7/site-packages
からのすべて。
Lambda関数を含む.pyファイルとともに、これらすべてのフォルダーとファイルを1つZipに入れます。 コピーされたすべてのファイルの図
この.Zipは10 MBより大きいため、ファイルを保存するためにS3バケットを作成しました。そこからファイルのリンクをコピーし、Lambda関数で「Amazon S3から.Zipをアップロード」で貼り付けました。
EC2インスタンスはshut downである可能性がありますが、もう必要ありません。
これで、numpyとpandasをインポートできました。私はmoviepyに慣れていませんが、Lambdaには262 144 000バイトの展開されていない展開パッケージサイズのlimitがあるため、scipyはすでに扱いにくいかもしれません。私はnumpyとscipyが一緒にすでにそれを超えているのではないかと心配しています。
ここの投稿は、AWS Lambda Deploymentパッケージに含めることができるライブラリファイルを使用してNumPyを静的にコンパイルする方法を見つけるのに役立ちます。このソリューションは、@ rouk1ソリューションのようにLD_LIBRARY_PATH値に依存しません。
コンパイルされたNumPyライブラリは https://github.com/vitolimandibhrata/aws-lambda-numpy からダウンロードできます。
NumPyをカスタムコンパイルする手順は次のとおりです。
AWS Linuxで新しいAWS ECインスタンスを準備します。
コンパイラの依存関係をインストールする
Sudo yum -y install python-devel
Sudo yum -y install gcc-c++
Sudo yum -y install gcc-gfortran
Sudo yum -y install libgfortran
NumPyの依存関係をインストールする
Sudo yum -y install blas
Sudo yum -y install lapack
Sudo yum -y install atlas-sse3-devel
/ var/task/libを作成して、ランタイムライブラリを含める
mkdir -p /var/task/lib
/ var/taskは、AWS Lambdaでコードが存在するルートディレクトリです。したがって、この場合は/ var/task/libの既知のフォルダーにある必要なライブラリファイルを静的にリンクする必要があります。
次のライブラリファイルを/ var/task/libにコピーします
cp /usr/lib64/atlas-sse3/liblapack.so.3 /var/task/lib/.
cp /usr/lib64/atlas-sse3/libptf77blas.so.3 /var/task/lib/.
cp /usr/lib64/atlas-sse3/libf77blas.so.3 /var/task/lib/.
cp /usr/lib64/atlas-sse3/libptcblas.so.3 /var/task/lib/.
cp /usr/lib64/atlas-sse3/libcblas.so.3 /var/task/lib/.
cp /usr/lib64/atlas-sse3/libatlas.so.3 /var/task/lib/.
cp /usr/lib64/atlas-sse3/libptf77blas.so.3 /var/task/lib/.
cp /usr/lib64/libgfortran.so.3 /var/task/lib/.
cp /usr/lib64/libquadmath.so.0 /var/task/lib/.
http://sourceforge.net/projects/numpy/files/NumPy/ から最新のnumpyソースコードを取得します
Numpyソースコードフォルダーに移動します(例:numpy-1.10.4)次のエントリでsite.cfgファイルを作成します
[atlas]
libraries=lapack,f77blas,cblas,atlas
search_static_first=true
runtime_library_dirs = /var/task/lib
extra_link_args = -lgfortran -lquadmath
-lgfortran -lquadmathフラグは、gfortranおよびquadmathライブラリをruntime_library_dirsで定義されたファイルと静的にリンクするために必要です。
NumPyをビルドする
python setup.py build
NumPyをインストールする
python setup.py install
ライブラリが/ var/task/lib内のファイルにリンクされているかどうかを確認します
ldd $PYTHON_HOME/lib64/python2.7/site-packages/numpy/linalg/lapack_lite.so
見るべき
linux-vdso.so.1 => (0x00007ffe0dd2d000)
liblapack.so.3 => /var/task/lib/liblapack.so.3 (0x00007ffad6be5000)
libptf77blas.so.3 => /var/task/lib/libptf77blas.so.3 (0x00007ffad69c7000)
libptcblas.so.3 => /var/task/lib/libptcblas.so.3 (0x00007ffad67a7000)
libatlas.so.3 => /var/task/lib/libatlas.so.3 (0x00007ffad6174000)
libf77blas.so.3 => /var/task/lib/libf77blas.so.3 (0x00007ffad5f56000)
libcblas.so.3 => /var/task/lib/libcblas.so.3 (0x00007ffad5d36000)
libpython2.7.so.1.0 => /usr/lib64/libpython2.7.so.1.0 (0x00007ffad596d000)
libgfortran.so.3 => /var/task/lib/libgfortran.so.3 (0x00007ffad5654000)
libm.so.6 => /lib64/libm.so.6 (0x00007ffad5352000)
libquadmath.so.0 => /var/task/lib/libquadmath.so.0 (0x00007ffad5117000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007ffad4f00000)
libc.so.6 => /lib64/libc.so.6 (0x00007ffad4b3e000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007ffad4922000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007ffad471d000)
libutil.so.1 => /lib64/libutil.so.1 (0x00007ffad451a000)
/lib64/ld-linux-x86-64.so.2 (0x000055cfc3ab8000)
2017年現在、NumPyとSciPyにはLambdaで動作するホイールがあります(パッケージにはプリコンパイルされたlibgfortran
とlibopenblas
が含まれます)。私の知る限り、MoviePyは純粋なPythonモジュールなので、基本的には次のようにできます。
pip2 install -t lambda moviepy scipy
次に、ハンドラーをlambda
ディレクトリにコピーしてZipします。ただし、50/250 MBのサイズ制限を超える可能性が高いことを除きます。役立つものがいくつかあります。
上記のポイントを自動化する例 script を次に示します。
最近可能になるもう1つの非常に簡単な方法は、LambCIがLambdaを模倣するために作成した素晴らしいdockerコンテナーを使用してビルドすることです: https://github.com/lambci/docker-lambda
lambci/lambda:build
コンテナは、AWS Lambdaに似ており、ほぼ完全なビルド環境が追加されています。シェルセッションを開始するには:
docker run -v "$PWD":/var/task -it lambci/lambda:build bash
セッション内:
export share=/var/task
easy_install pip
pip install -t $share numpy
または、virtualenvで:
export share=/var/task
export PS1="[\u@\h:\w]\$ " # required by virtualenv
easy_install pip
pip install virtualenv
# ... make the venv, install numpy, and copy it to $share
後で、メインのlambci/lambdaコンテナーを使用してビルドをテストできます。
2018年現在、AWS EC2のPython3に外部モジュールをインストールする手順:
Amazon Linux AMI 201709でEC2を起動します。
秘密鍵と公開鍵を使用してPuTTYでsshを実行し、スーパーユーザーになります。
Python 3をインストールして仮想環境を作成し、それをデフォルトにします
yum install python36 python36-virtualenv python36-pip
virtualenv -p python3.6 /tmp/my_python_lib
source /tmp/my_python_lib/bin/activate
which python --to check which version s installed
pip3 install numpy
Winscpを使用して、サイトパッケージおよびdistパッケージの下のファイルをローカルコンピューターにコピーします。
実際の場所を見つけるには、grepコマンドを使用します---
grep -r dist-packages *.
これらのパッケージは、libとlib64の両方の中にあります。
Siteおよびdistパッケージは次の場所にあります。
/tmp/my_python_lib/lib64/python3.6,
/tmp/my_python_lib/lib/python3.6
スクリプトファイルと共にこれらのパッケージを圧縮し、ラムダでアクセスできるS3にアップロードします。ルートフォルダーを圧縮する代わりに、すべてのファイルを選択して圧縮するか、圧縮フォルダーに送信する必要があります。
追加のヒント:
すべてのパッケージを1つのディレクトリにインストールする場合は、次のコマンドを使用できます。
pip install --upgrade --target=/tmp/my_python_lib/lib/python3.6/dist-packages pandas
2018年8月現在、おそらく最も簡単な方法は 新しいAWS Cloud9環境 を開始することです。次に、環境内にLambda関数を作成します。次に、これをCloud9コマンドラインで実行します。
cd YourApplicationName
/venv/bin/pip install scipy -t .
/venv/bin/pip install numpy -t .
/venv/bin/pip install moviepy -t .
これで、lambda_handler関数でモジュールをインポートできます。
2018年11月こんにちは友人、この投稿は私にとって非常に役立ちます。ただし、これまでの回答はあまり自動化されていません。ここでPythonスクリプトとチュートリアルを書いた https://Gist.github.com/steinwaywhw/6a6a25d594cc07146c60af943f74c16f を使用して、コンパイルされたPythonパッケージの作成を自動化EC2のpip
およびvirtualenv
すべてがPython(Boto3)、bashスクリプト、Webコンソール、awscli
でありません。
自動化のほかに1つの変更がありますが、それは改善だと思います。 lib
パッケージとlib64
パッケージをすべてマージする代わりに、フォルダー構造を維持したまま、Python仮想環境全体をEC2からダウンロードしました。これらの2つのフォルダーをマージすることの意図する意味がわかりません。一部のパッケージが他のパッケージをオーバーライドする場合はどうでしょうか?さらに、公式の仮想環境を偽造することは、独自の環境を展開するよりも安全な方法です。
ダウンロードした仮想環境が機能するように、Lambda関数のソースコードは、ボイラープレートコードを追加して、sys.path
を使用してPython検索パスを更新します。 Python仮想環境の目的のsys.path
は、
import sys
の後にprint(sys.path)
を実行します。そこから始めて、必要に応じて変更できます。パッケージ化された仮想環境からnumpy
およびその他のパッケージをロードするためにLambda関数に追加する定型コードのスニペットを以下に貼り付けます。私の場合、numpy
に依存するpandas_datareader
をロードしました。
import os
import sys
# https://docs.aws.Amazon.com/lambda/latest/dg/current-supported-versions.html
workdir = os.getenv('LAMBDA_TASK_ROOT')
version = f'{sys.version_info[0]}.{sys.version_info[1]}'
additionals = [f'{workdir}/venv/lib64/python{version}/site-packages',
f'{workdir}/venv/lib64/python{version}/lib-dynload',
f'{workdir}/venv/lib64/python{version}/dist-packages',
f'{workdir}/venv/lib/python{version}/dist-packages',
f'{workdir}/venv/lib/python{version}/site-packages']
sys.path = additionals + sys.path
import pandas_datareader as pdr
@ attila-tanyiによって投稿されたステップがAmazon Linuxで正しく機能することを確認できます。デフォルトのリポジトリからAmazon Linuxのdockerコンテナが利用可能であるため、EC2を使用する必要がないことだけを追加します。
docker pull amazonlinux && docker run -it amazonlinux
# Follow @attila-tanyi steps
# Note - Sudo is not necessary here
アプリケーションに埋め込まれたDockerfileを使用して、Lambdaにビルドしてデプロイします。
@Vito Limandibhrataの答えは好きですが、numpy == 1.11.1のruntime_library_dirsでnumpyを構築するだけでは不十分だと思います。誰かがsite-cfgが無視されると思う場合は、次のことを行ってください。
cp /usr/lib64/atlas-sse3/*.a /var/task/lib/
* numpyをビルドするには、atlas-sse3の下の.aファイルが必要です。また、次を実行する必要がある場合があります。
python setup.py config
numpyの設定を確認します。さらに必要な場合は、次のメッセージが表示されます。
atlas_threads_info:
Setting PTATLAS=ATLAS libraries ptf77blas,ptcblas,atlas not found in /root/Envs/skl/lib
libraries lapack_atlas not found in /root/Envs/skl/lib
libraries ptf77blas,ptcblas,atlas not found in /usr/local/lib64
libraries lapack_atlas not found in /usr/local/lib64
libraries ptf77blas,ptcblas,atlas not found in /usr/local/lib
libraries lapack_atlas not found in /usr/local/lib
libraries lapack_atlas not found in /usr/lib64/atlas-sse3
<class 'numpy.distutils.system_info.atlas_threads_info'>
Setting PTATLAS=ATLAS
Setting PTATLAS=ATLAS
Setting PTATLAS=ATLAS
Setting PTATLAS=ATLAS
libraries lapack not found in ['/var/task/lib']
Runtime library lapack was not found. Ignoring
libraries f77blas not found in ['/var/task/lib']
Runtime library f77blas was not found. Ignoring
libraries cblas not found in ['/var/task/lib']
Runtime library cblas was not found. Ignoring
libraries atlas not found in ['/var/task/lib']
Runtime library atlas was not found. Ignoring
FOUND:
extra_link_args = ['-lgfortran -lquadmath']
define_macros = [('NO_ATLAS_INFO', -1)]
language = f77
libraries = ['lapack', 'ptf77blas', 'ptcblas', 'atlas', 'lapack', 'f77blas', 'cblas', 'atlas']
library_dirs = ['/usr/lib64/atlas-sse3']
include_dirs = ['/usr/include']
その後、site-cfgは無視されます。
ヒント:pipを使用して、runtime_library_dirsでnumpyをビルドする場合は、~/.numpy-site.cfg
を作成し、次を追加することをお勧めします。
[atlas]
libraries = lapack,f77blas,cblas,atlas
search_static_first = true
runtime_library_dirs = /var/task/lib
extra_link_args = -lgfortran -lquadmath
numpyは.numpy-site.cfgファイルを認識します。それは非常にシンプルで簡単な方法です。