SpaCy 模型不会在 AWS Lambda 中加载
SpaCy model won't load in AWS Lambda
有人让 SpaCy 2.0 在 AWS Lambda 中工作吗?我已经正确地压缩和打包了所有内容,因为如果我测试它,我可以从我的 lambda 函数中获得 return 的通用字符串。但是当我执行下面的简单功能进行测试时,它会停顿大约 10 秒,然后 return 为空,而且我没有收到任何错误消息。我确实将 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
当我在不使用它的情况下加载模型包时,它也 return 是空的,但如果我将其注释掉,它会按预期向我发送字符串,因此它必须与加载模型有关。
import spacy
nlp = spacy.load('en_core_web_sm') #model package included
def lambda_handler(event, context):
msg = 'message returned'
return msg
知道这可能会很简单。答案是没有足够的内存分配给 运行 Lambda 函数——我发现我必须将它最小地增加到接近最大 2816 MB 才能使上面的示例工作。值得注意的是,在上个月之前不可能达到这么高:
我将其调至最大 3008 MB 以处理更多文本,现在一切似乎都正常。
要优化模型加载,您必须将其存储在 S3 上,并使用您自己的脚本将其下载到 lambda 中的 tmp 文件夹,然后从中加载到 spacy。
从 S3 和 运行 下载需要 5 秒。这里好的优化是将模型保存在温暖的容器中并检查它是否已经下载。在温暖的容器代码需要 0.8 秒到 运行.
这里是 link 代码和包示例:
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 billion')
for token in doc:
print(token.text, token.pos_, token.dep_)
return 'finished'
P.S。要在 AWS Lambda 中打包 spacy,您必须去除共享库。
对我有用的是 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 a
ls -d */ | grep -v | xargs rm -rf`,然后压缩内容以使其处于 Lambda 的限制之下。
有人让 SpaCy 2.0 在 AWS Lambda 中工作吗?我已经正确地压缩和打包了所有内容,因为如果我测试它,我可以从我的 lambda 函数中获得 return 的通用字符串。但是当我执行下面的简单功能进行测试时,它会停顿大约 10 秒,然后 return 为空,而且我没有收到任何错误消息。我确实将 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
当我在不使用它的情况下加载模型包时,它也 return 是空的,但如果我将其注释掉,它会按预期向我发送字符串,因此它必须与加载模型有关。
import spacy
nlp = spacy.load('en_core_web_sm') #model package included
def lambda_handler(event, context):
msg = 'message returned'
return msg
知道这可能会很简单。答案是没有足够的内存分配给 运行 Lambda 函数——我发现我必须将它最小地增加到接近最大 2816 MB 才能使上面的示例工作。值得注意的是,在上个月之前不可能达到这么高:
我将其调至最大 3008 MB 以处理更多文本,现在一切似乎都正常。
要优化模型加载,您必须将其存储在 S3 上,并使用您自己的脚本将其下载到 lambda 中的 tmp 文件夹,然后从中加载到 spacy。
从 S3 和 运行 下载需要 5 秒。这里好的优化是将模型保存在温暖的容器中并检查它是否已经下载。在温暖的容器代码需要 0.8 秒到 运行.
这里是 link 代码和包示例: 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 billion')
for token in doc:
print(token.text, token.pos_, token.dep_)
return 'finished'
P.S。要在 AWS Lambda 中打包 spacy,您必须去除共享库。
对我有用的是 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 a
ls -d */ | grep -v | xargs rm -rf`,然后压缩内容以使其处于 Lambda 的限制之下。