Подтвердить что ты не робот

Использование кипения, scipy и numpy в амазонке лямбда

Я хотел бы генерировать видео с помощью функции AWS Lambda.

Я выполнил следующие инструкции здесь и здесь.

И теперь у меня есть следующий процесс для создания моей функции Lambda:

Шаг 1

Оставьте a 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 на своем ноутбуке. Затем запустите этот script, чтобы создать 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 script на данный момент является только тестом, чтобы убедиться, что стек в порядке:

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. Когда я тестирую функцию, я получаю следующее 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 не нашел основной каталог, который присутствует в структуре папок.

EDIT:

Следуя совету @jarmod, я уменьшил функцию 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
4b9b3361

Ответ 1

С помощью всех сообщений в этой цепочке это решение для записей:

Чтобы это сработало, вам нужно:

  • запустите экземпляр EC2 с не менее чем 2GO RAM (чтобы скомпилировать 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
    
  • Скопируйте в локальную машину все содержимое каталогов (кроме _markerlib, pip *, pkg_resources, setuptools * и easyinstall *) в папке stack:

    • 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, содержащую:

    • все зависимости python от root
    • все разделяемые библиотеки в подпапке 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)
    
  • напишите movie_maker.py script, который зависит от moviepy, NumPy,...

  • добавьте их в script в файл stack.zip zip -r9 lambda.zip *.py

  • загрузите zip в S3 и используйте его как источник для lambda

Вы также можете скачать stack.zip здесь.

Ответ 2

Я также следил за вашей первой ссылкой и смог импортировать numpy и pandas в функцию Lambda (в Windows):

  • Начал создание > t2.micro экземпляра EC2 с 64-разрядным Amazon Linux AMI 2015.09. 1 и использовал Putty для SSH в.
  • Пробовали те же самые команды, которые вы использовали, и рекомендованные статьей 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
    
  • Установлен пакет :

    sudo ~/env/bin/pip2.7 install numpy
    sudo ~/env/bin/pip2.7 install pandas
    
  • Затем, используя WinSCP, я вошел в систему и загрузил все (кроме _markerlib, pip *, pkg_resources, setuptools * и easyinstall *) из /home/ec2-user/env/lib/python2.7/dist-packages, и все от /home/ec2-user/env/lib64/python2.7/site-packages из экземпляра EC2.

  • Я поместил все эти папки и файлы в один zip вместе с файлом .py, содержащим функцию Lambda. иллюстрация всех скопированных файлов

  • Поскольку этот .zip больше 10 МБ, я создал ведро S3, чтобы сохранить файл. Я скопировал ссылку на файл оттуда и вставил в "Загрузить .ZIP от Amazon S3" в функции Lambda.

  • Экземпляр EC2 может быть выключен, он больше не нужен.

При этом я могу импортировать numpy и pandas. Я не знаком с видеороликом, но scipy уже может быть сложным, поскольку Lambda имеет ограничение для распакованного пакета развертывания размером 262 144 000 байт. Я боюсь, что numpy и scipy вместе уже закончились.

Ответ 3

Здесь мне помогают найти способ статической компиляции NumPy с файлами библиотек, которые могут быть включены в пакет развертывания AWMS Lambda. Это решение не зависит от значения LD_LIBRARY_PATH, как в решении @rouk1.

Скомпилированную библиотеку NumPy можно загрузить с https://github.com/vitolimandibhrata/aws-lambda-numpy

Ниже приведены шаги для пользовательской компиляции NumPy

Инструкции по сборке этого пакета с нуля

Подготовьте новый экземпляр AWS EC с AWS Linux.

Установить зависимости компилятора

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/.

Получите последний исходный код numpy из http://sourceforge.net/projects/numpy/files/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)

Ответ 4

Другим, очень простым методом, который возможно в наши дни, является создание с использованием удивительных контейнеров докеров, которые LambCI сделал для имитации Lambda: 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="[\[email protected]\h:\w]\$ " # required by virtualenv
easy_install pip
pip install virtualenv
# ... make the venv, install numpy, and copy it to $share

Позже вы можете использовать основной контейнер lambci/lambda для проверки сборки.

Ответ 5

По состоянию на 2017 год NumPy и SciPy имеют колеса, которые работают на Lambda (пакеты включают предварительно скомпилированные libgfortran и libopenblas). Насколько я знаю, MoviePy - это чистый модуль Python, поэтому вы можете:

pip2 install -t lambda moviepy scipy

Затем скопируйте обработчик в каталог lambda и запишите его. Кроме того, вы, скорее всего, превысите ограничения на размер 50/250 МБ. Есть несколько вещей, которые могут помочь:

  • удалить .pycs, docs, тесты и другие ненужные части;
  • оставить одну копию общих библиотек NumPy и SciPy;
  • библиотеки библиотек несущественных элементов, таких как отладочные символы;
  • сжатие архива с использованием более высоких настроек.

Здесь приведен пример script, который автоматизирует указанные выше пункты.

Ответ 6

Мне нравится @Vito Limandibhrata, но я думаю, что этого недостаточно для создания numpy с runtime_library_dirs в numpy == 1.11.1. Если кто-то думает, что сайт-cfg игнорируется, выполните следующие действия:

cp /usr/lib64/atlas-sse3/*.a /var/task/lib/

*. Файлы для atlas-sse3 необходимы для создания numpy. Кроме того, вам может потребоваться запустить следующее:

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']

то сайт-cfg будет проигнорирован.

Совет. Если pip используется для создания numpy с runtime_library_dirs, лучше создать ~/.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. Это довольно простой и простой способ.

Ответ 7

Я могу подтвердить, что действия, выполняемые @attila-tanyi, работают правильно в Amazon Linux. Я бы добавил, что нет необходимости использовать EC2, так как есть контейнер докеров Amazon Linux, доступный из репозитория по умолчанию.

docker pull amazonlinux && docker run -it amazonlinux
# Follow @attila-tanyi steps
# Note - sudo is not necessary here

Я использую Dockerfile, встроенный в мое приложение, для сборки и развертывания в Lambda.