SpaCy模型无法在AWS Lambda中加载。

7

有人在AWS Lambda中成功使用SpaCy 2.0吗?我已经正确地压缩和打包了所有内容,因为如果我测试它,可以从我的lambda函数返回通用字符串。但是当我执行下面的简单函数进行测试时,它会停顿约10秒钟,然后返回空,并且我没有收到任何错误消息。我确实将Lambda超时设置为60秒,所以这不是问题。

import spacy

nlp = spacy.load('en_core_web_sm') #model package included

def lambda_handler(event, context):
    doc = nlp(u'They are')
    msg = doc[0].lemma_
    return msg

当我加载模型包却不使用它时,也会返回空值。但是,如果我注释掉它,它会按预期向我发送字符串。所以问题肯定出在加载模型上面。
import spacy

nlp = spacy.load('en_core_web_sm') #model package included

def lambda_handler(event, context):
    msg = 'message returned'
    return msg
3个回答

7
为了优化模型加载,您需要将其存储在S3上,并使用自己的脚本将其下载到lambda的tmp文件夹中,然后从其中加载到spacy中。
从S3下载并运行需要5秒钟。这里的良好优化是将模型保留在暖容器中,并检查是否已经下载。在暖容器中,代码运行需要0.8秒钟。
这是代码和示例的链接: https://github.com/ryfeus/lambda-packs/blob/master/Spacy/source2.7/index.py
import spacy
import boto3
import os


def download_dir(client, resource, dist, local='/tmp', bucket='s3bucket'):
    paginator = client.get_paginator('list_objects')
    for result in paginator.paginate(Bucket=bucket, Delimiter='/', Prefix=dist):
        if result.get('CommonPrefixes') is not None:
            for subdir in result.get('CommonPrefixes'):
                download_dir(client, resource, subdir.get('Prefix'), local, bucket)
        if result.get('Contents') is not None:
            for file in result.get('Contents'):
                if not os.path.exists(os.path.dirname(local + os.sep + file.get('Key'))):
                     os.makedirs(os.path.dirname(local + os.sep + file.get('Key')))
                resource.meta.client.download_file(bucket, file.get('Key'), local + os.sep + file.get('Key'))

def handler(event, context):
    client = boto3.client('s3')
    resource = boto3.resource('s3')
    if (os.path.isdir("/tmp/en_core_web_sm")==False):
        download_dir(client, resource, 'en_core_web_sm', '/tmp','ryfeus-spacy')
    spacy.util.set_data_path('/tmp')
    nlp = spacy.load('/tmp/en_core_web_sm/en_core_web_sm-2.0.0')
    doc = nlp(u'Apple is looking at buying U.K. startup for $1 billion')
    for token in doc:
        print(token.text, token.pos_, token.dep_)
    return 'finished'

P.S. 要在 AWS Lambda 中打包 spacy,您需要剥离共享库。


你能分享一下“剥离共享库”的链接吗?-谢谢 - Itay Livni
@ItayLivni 你解决了如何剥离库的问题吗? - Nagarajan Shanmuganathan
@NagarajanShanmuganathan,最好的方法是剥离掉Spacy中所有未使用的语言,因为它们会占用包中很多空间。我创建了一个代码片段,你可以使用它来实现:https://gist.github.com/jshhrrsn/5377b9dd282ef51f5564f1347a7d5aef - mdmjsh

5

2
您是如何在 AWS Lambda 中安装 Spacy 模块的? - iksnae
1
我将它安装在 EC2 上的 Amazon AMI 实例中,然后将包和依赖项复制到本地部署包中与我的 Lambda 函数一起,并将其压缩为部署文件(https://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html)。 - pynewb
Spacy安装时不带模型大小为290MB。你是如何将其缩小到250MB以下的? - JAB
Spacy 2.0?我记不清它需要哪些依赖项,但它比250mb小得多。 - pynewb
@JAB 你弄清楚如何在AWS Lambda中安装它了吗? - Jun

1
我成功的做法是进入 `/lib/Python/site-packages/` 目录并删除我不需要的语言模型。比如说,我只需要英文语言模型,所以在我的目录中,我只需要运行 `ls -d */ | grep -v en | xargs rm -rf`,然后将内容压缩以满足 Lambda 的限制。保留html标签。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接