【问题标题】:SpaCy model won't load in AWS LambdaSpaCy 模型不会在 AWS Lambda 中加载
【发布时间】:2017-12-19 02:33:01
【问题描述】:

有人让 SpaCy 2.0 在 AWS Lambda 中工作吗?我已经正确压缩和打包了所有东西,因为如果我测试它,我可以从我的 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

【问题讨论】:

    标签: aws-lambda spacy


    【解决方案1】:

    知道这可能会很简单。答案是没有足够的分配内存来运行 Lambda 函数 - 我发现我必须将其最小限度地增加到接近最大 2816 MB 才能使上面的示例正常工作。值得注意的是,在上个月之前不可能达到这么高:

    https://aws.amazon.com/about-aws/whats-new/2017/11/aws-lambda-doubles-maximum-memory-capacity-for-lambda-functions/

    我把它调到最大 3008 MB 以处理更多文本,现在一切似乎都很好。

    【讨论】:

    • 你是如何将 spacy 模块安装到 AWS Lambda 中的?
    • 我将它安装在 EC2 上的 Amazon AMI 实例上,然后使用我的 lambda 函数将包和依赖项复制到本地部署包中,然后将其压缩以进行部署 (docs.aws.amazon.com/lambda/latest/dg/…)
    • 没有模型的 spacy 安装是 290mb。你是怎么把它降到 250mb 以下的?
    • Spacy 2.0?我不记得它需要什么依赖项,但它远小于 250mb。
    • @JAB 你知道如何在 AWS Lambda 中安装它吗?
    【解决方案2】:

    要优化模型加载,您必须将其存储在 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'
    

    附:要在 AWS Lambda 中打包 spacy,您必须剥离共享库。

    【讨论】:

    • 你能分享一个关于如何“剥离共享库”的链接吗? -谢谢
    • @ItayLivni 你确定谁来剥离图书馆了吗?
    • @NagarajanShanmuganathan 最好的方法是去除 spacy 中所有未使用的语言,因为它们在包中占用了大量空间。我创建了一个可以用来执行此操作的要点:gist.github.com/jshhrrsn/5377b9dd282ef51f5564f1347a7d5aef
    【解决方案3】:

    对我有用的是cd进入<YOUR_ENV>/lib/Python<VERSION>/site-packages/ and removing the language models I didn't need. For example, I only needed the English language model so once in my own site-packages directory I just needed to run als -d */ | grep -v en | xargs rm -rf`,然后压缩内容以使其在 Lambda 的限制下。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-05
      • 2016-03-30
      • 2019-11-17
      • 1970-01-01
      相关资源
      最近更新 更多