在亚马逊lambda中使用电影,scipy和numpy

我想使用AWS Lambdafunction生成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 

我也跟着你的第一个链接,并设法导入nambypandas这样的Lambda函数(在Windows上):

  1. 使用64位Amazon Linux AMI 2015.09.1启动了一个(免费层) t2.micro EC2实例 ,并使用Putty连接到SSH。
  2. 试了一下你用过的和亚马逊文章推荐的命令

     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 
  3. 创build虚拟环境

     virtualenv ~/env source ~/env/bin/activate 
  4. 安装软件包

     sudo ~/env/bin/pip2.7 install numpy sudo ~/env/bin/pip2.7 install pandas 
  5. 然后,使用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

  6. 我将所有这些文件夹和文件放入一个zip文件,以及包含Lambda函数的.py文件。 所有复制的文件的插图

  7. 由于这个.zip大于10 MB,我创build了一个S3存储区来存储文件。 我从那里复制了文件的链接,并在Lambda函数中“从Amazon S3上传一个.ZIP”中粘贴。

  8. EC2实例可以closures ,不再需要了。

有了这个,我可以导入numpy和pandas。 我不熟悉moviepy,但scipy可能已经非常棘手,因为Lambda在262 144 000字节的解压缩部署包大小有限制 。 我害怕numpy和scipy在一起已经结束了。

在这个线程的所有post的帮助下,这里是logging的解决scheme:

为了得到这个工作,你需要:

  1. 启动至less2G内存的EC2实例(可以编译NumPySciPy

  2. 安装所需的依赖关系

     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 
  3. 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
  4. 从您的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
  5. 把它们放在stack文件夹的lib子文件夹中

  6. imageioimageio的一个依赖,你需要下载一些二进制版本的依赖: libfreeimageffmpeg ; 他们可以在这里find。 将它们放在堆栈文件夹的根目录下,并将libfreeimage-3.16.0-linux64.so重命名为libfreeimage.so

  7. 你现在应该有一个stack文件夹包含:

    • 根目录下的所有python依赖项
    • lib子文件夹中的所有共享库
    • 在根目录下的ffmpeg二进制文件
    • libfreeimage.so在根目录下
  8. 压缩此文件夹: zip -r9 stack.zip . -x ".*" -x "*/.*" zip -r9 stack.zip . -x ".*" -x "*/.*"

  9. 使用下面的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) 
  10. 写一个movie_maker.py脚本取决于moviepynumpy ,…

  11. 将这些脚本添加到您的stack.zip文件zip -r9 lambda.zip *.py

  12. 将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上工作(包中包括预编译的libgfortranlibopenblas )。 据我所知,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。