在亚马逊lambda中使用电影,scipy和numpy
我想使用AWS Lambda
function生成video。
我遵循这里和这里find的指示。
我现在有以下过程来构build我的Lambda
函数:
步骤1
启动Amazon Linux EC2
实例并以root身份运行它:
#! /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/*
第2步
我将所得到的tarball提交给我的笔记本电脑。 然后运行这个脚本来build立一个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
脚本目前只是一个testing,看看堆栈是否正常:
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')
第3步
然后我把结果存档上传到S3,成为我的lambda
函数的源码。 当我testing函数时,我得到以下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不能find文件夹结构中存在的核心目录。
编辑:
遵循@jarmod的build议我已经减less了lambda
函数:
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
我也跟着你的第一个链接,并设法导入namby和pandas这样的Lambda函数(在Windows上):
- 使用64位Amazon Linux AMI 2015.09.1启动了一个(免费层) t2.micro EC2实例 ,并使用Putty连接到SSH。
-
试了一下你用过的和亚马逊文章推荐的命令 :
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
-
创build虚拟环境 :
virtualenv ~/env source ~/env/bin/activate
-
安装软件包 :
sudo ~/env/bin/pip2.7 install numpy sudo ~/env/bin/pip2.7 install pandas
-
然后,使用WinSCPlogin并从 /home/ec2-user/env/lib/python2.7/dist-packages 下载所有内容(_markerlib,pip *,pkg_resources,setuptools *和easyinstall *),以及
/home/ec2-user/env/lib64/python2.7/site-packages
。 -
我将所有这些文件夹和文件放入一个zip文件,以及包含Lambda函数的.py文件。 所有复制的文件的插图
-
由于这个.zip大于10 MB,我创build了一个S3存储区来存储文件。 我从那里复制了文件的链接,并在Lambda函数中“从Amazon S3上传一个.ZIP”中粘贴。
-
EC2实例可以closures ,不再需要了。
有了这个,我可以导入numpy和pandas。 我不熟悉moviepy,但scipy可能已经非常棘手,因为Lambda在262 144 000字节的解压缩部署包大小有限制 。 我害怕numpy和scipy在一起已经结束了。
在这个线程的所有post的帮助下,这里是logging的解决scheme:
为了得到这个工作,你需要:
-
启动至less2G内存的
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
实例获取所有必需的共享库:-
libatlas.so.3
-
libf77blas.so.3
-
liblapack.so.3
-
libptf77blas.so.3
-
libcblas.so.3
-
libgfortran.so.3
-
libptcblas.so.3
-
libquadmath.so.0
-
-
把它们放在
stack
文件夹的lib
子文件夹中 -
imageio
是imageio
的一个依赖,你需要下载一些二进制版本的依赖:libfreeimage
和ffmpeg
; 他们可以在这里find。 将它们放在堆栈文件夹的根目录下,并将libfreeimage-3.16.0-linux64.so
重命名为libfreeimage.so
-
你现在应该有一个
stack
文件夹包含:- 根目录下的所有python依赖项
-
lib
子文件夹中的所有共享库 - 在根目录下的
ffmpeg
二进制文件 -
libfreeimage.so
在根目录下
-
压缩此文件夹:
zip -r9 stack.zip . -x ".*" -x "*/.*"
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)
-
写一个
movie_maker.py
脚本取决于moviepy
,numpy
,… -
将这些脚本添加到您的stack.zip文件
zip -r9 lambda.zip *.py
-
将zip上传到
S3
并将其用作您的lambda
的源代码
你也可以在这里下载stack.zip
。
这里的post帮助我find一种方法来静态编译可以包含在AWS Lambda Deployment包中的库文件的NumPy。 此解决scheme不依赖于@ rouk1解决scheme中的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
创build/ 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使用以下条目创build一个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中定义的文件
build立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
目录并压缩。 除此之外,你很可能会超过50/250 MB的大小限制。 有几件事可以帮助:
- 删除.pycs,文档,testing和其他不必要的部分;
- 留下NumPy和SciPy的共同库的一个副本;
- 对无关紧要的部分进行条带库,例如debugging符号;
- 使用更高的设置压缩存档。
以下是一个自动执行以上几点的示例脚本 。
另一种非常简单的方法是使用LambCI模仿Lambda的真棒docker容器来构build: https : //github.com/lambci/docker-lambda
lambci/lambda:build
容器类似于AWS Lambda,增加了大部分完整的构build环境。 在其中启动一个shell会话:
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
稍后,您可以使用主要的lambda / lambda容器来testing您的构build。
我喜欢@Vito Limandibhrata的答案,但我认为在numpy == 1.11.1中用runtime_library_dirsbuild立numpy是不够的。 如果有人认为site-cfg被忽略,请执行以下操作:
cp /usr/lib64/atlas-sse3/*.a /var/task/lib/
* .a文件在atlas-sse3下需要build立numpy。 另外,您可能需要运行以下命令:
python setup.py config
检查numpyconfiguration。 如果需要更多的东西,你会看到下面的消息:
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构buildnumpy,则最好创build~/.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文件。 这是相当简单和容易的方法。
我可以确认@ attila-tanyi发布的步骤在Amazon Linux下正常工作。 我只会补充说,不需要使用EC2,因为默认存储库中有一个Amazon Linux docker容器可用。
docker pull amazonlinux && docker run -it amazonlinux # Follow @attila-tanyi steps # Note - sudo is not necessary here
我使用我的应用程序中embedded的Dockerfile来构build和部署到Lambda。