AWS Lambda, Docker 및 AWS CDK를 사용하여 Tensorflow 모델을 생산에 투입
28402 단어 cdkawsmachinelearningtensorflow
Tensorflow
라이브러리를 보유할 수 있을 만큼 큰 Lambda 함수를 구축하려면 . S3
에서 모델을 로드하지 않아도 됩니다. Github 저장소를 찾을 수 있습니다here.
스택과 기능 구축을 시작합시다!
스택 설계
나는 우리가 찾고 있는 기능을 유지하면서 이 디자인을 가능한 한 최소화하려고 노력했습니다. 연결된 파일 시스템을 포함하여
Tensorflow
가 설치된 도커 배포 Lambda 함수와 HTTP로 쿼리할 수 있는 HTTPS 엔드포인트가 있습니다. GET 메시지.from aws_cdk import CfnOutput as Output
from aws_cdk import CfnResource, Duration, RemovalPolicy, Stack
from aws_cdk import aws_ec2 as ec2
from aws_cdk import aws_efs as efs
from aws_cdk import aws_lambda as _lambda
from aws_cdk import aws_s3 as s3
from aws_cdk import aws_s3_deployment as s3_deployment
from constructs import Construct
class CdkTensorflowStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
# Let's list all of our physical resources getting deployed
self.vpc = None
self.access_point = None
self.prediction_lambda = None
self.models_bucket = None
# convenient deployment
self.build_infrastructure()
def build_infrastructure(self):
self.build_vpc()
self.build_filesystem()
self.build_lambda()
self.build_bucket()
self.build_function_url()
def build_vpc(self):
# Need the VPC for the lambda filesystem
self.vpc = ec2.Vpc(scope=self, id="VPC", vpc_name="ExampleVPC")
def build_filesystem(self):
file_system = efs.FileSystem(
scope=self,
id="ExampleEFS",
vpc=self.vpc,
file_system_name="ExampleEFS",
removal_policy=RemovalPolicy.DESTROY,
)
# create a new access point from the filesystem
self.access_point = file_system.add_access_point(
"AccessPoint",
# set /export/lambda as the root of the access point
path="/export/lambda",
# as /export/lambda does not exist in a new efs filesystem, the efs will create the directory with the following createAcl
create_acl=efs.Acl(
owner_uid="1001", owner_gid="1001", permissions="750"
),
# enforce the POSIX identity so lambda function will access with this identity
posix_user=efs.PosixUser(uid="1001", gid="1001"),
)
def build_lambda(self):
self.prediction_lambda = _lambda.DockerImageFunction(
scope=self,
id="TensorflowLambda",
function_name="TensorflowLambda",
code=_lambda.DockerImageCode.from_image_asset(
directory="lambda_funcs/TensorflowLambda"
),
# I've found inferences can be made with my simple model in < 20 sec
timeout=Duration.seconds(60 * 0.5),
memory_size=128 * 6 * 1, # mb
# Attach the EFS file system
filesystem=_lambda.FileSystem.from_efs_access_point(
ap=self.access_point, mount_path="/mnt/models"
)
if self.access_point
else None,
# Needs to be placed in the same VPC as the EFS file system
vpc=self.vpc,
)
def build_bucket(self):
self.models_bucket = s3.Bucket(
scope=self,
id="ExampleModelsBucket",
bucket_name="models-bucket",
# These settings will make sure things get deleted when we take down the stack
removal_policy=RemovalPolicy.DESTROY,
auto_delete_objects=True,
)
# We can add files to our new bucket from a local source
s3_deployment.BucketDeployment(
self,
"save_model_to_s3",
sources=[s3_deployment.Source.asset("model_files")],
destination_bucket=self.models_bucket,
)
# Make sure to give the lambda permission to retrieve the model file
self.models_bucket.grant_read(identity=self.prediction_lambda)
def build_function_url(self):
# Set up the Lambda Function URL
cfnFuncUrl = CfnResource(
scope=self,
id="lambdaFuncUrl",
type="AWS::Lambda::Url",
properties={
"TargetFunctionArn": self.prediction_lambda.function_arn,
"AuthType": "NONE",
"Cors": {"AllowOrigins": ["*"]},
},
)
# Give everyone permission to invoke the Function URL
CfnResource(
scope=self,
id="funcURLPermission",
type="AWS::Lambda::Permission",
properties={
"FunctionName": self.prediction_lambda.function_name,
"Principal": "*",
"Action": "lambda:InvokeFunctionUrl",
"FunctionUrlAuthType": "NONE",
},
)
# Get the Function URL as output
Output(
scope=self,
id="funcURLOutput",
value=cfnFuncUrl.get_att(attribute_name="FunctionUrl").to_string(),
)
람다 함수 설계
cdk_tensorflow/lambda_funcs/TensorflowLambda/tensorflow_lambda.py
다시 말하지만, 최소한의 작업 예제를 보여주려고 합니다. 이 Lambda 함수는 EFS에서 모델을 로드하려고 시도합니다. 찾을 수 없는 경우(처음 실행할 때와 같이) 생성한 S3 버킷에서 모델을 복사하고 EFS에 저장한 다음 다시 로드합니다. 모델이 로드되면 이를 사용하여 추론할 수 있습니다. 처리기는 추론을 쿼리한 클라이언트로 다시 보냅니다.
# import tempfile
from pathlib import Path
from typing import Tuple
import boto3
import joblib
def get_model() -> Tuple:
"""
Gets model from EFS if exists. Otherwise load model from S3, save to EFS
"""
local_path = Path(f"/mnt/models/model.tensorflow")
try:
with open(local_path, "rb") as f:
f.seek(0)
model = joblib.load(f)
except FileNotFoundError:
client = boto3.client("s3")
# Save model to EFS
client.download_file(
"models-bucket",
"model.tensorflow",
str(local_path),
)
with open(local_path, "rb") as f:
f.seek(0)
model = joblib.load(f)
return model
model = get_model()
def get_prediction(model, input_data):
# Do what you need to do to feed input data to your model
return 1
# return output_data
def handler(event, context):
# This is the data we get from the client query
data = event["queryStringParameters"]["q"]
# I pass the data as a list to the API, but it gets converted into a string.
# This is some fancy way to get back the list from the str(list)
split_str = data.split(",")
formatted_data = (
[float(split_str[0].split("[")[-1])]
+ [float(y) for y in split_str[1:-1]]
+ [float(split_str[-1].split("]")[0])]
)
assert isinstance(formatted_data, list)
# Get a prediction by feeding your formatted input data into model
prediction = get_prediction(model=model, input_data=formatted_data)
response = {
"isBase64Encoded": False,
"statusCode": 200,
"headers": {
"Access-Control-Allow-Origin": "*",
},
"body": f"The predicted value is {prediction}",
}
return response
cdk_tensorflow/lambda_funcs/TensorflowLambda/Dockerfile
Lambda 함수를 빌드하기 위한 빌드 지침을 제공합니다.
FROM amazon/aws-lambda-python:latest
LABEL maintainer="Wesley Cheek"
RUN yum update -y && \
yum install -y python3 python3-dev python3-pip gcc && \
rm -Rf /var/cache/yum
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY tensorflow_lambda.py ./
CMD ["tensorflow_lambda.handler"]
cdk_tensorflow/lambda_funcs/TensorflowLambda/requirements.txt
joblib
# I use tensorflow-cpu because it's half the size of the gpu version and Lambda doesn't have a GPU anyway.
tensorflow-cpu
boto3
전개
cdk deploy
를 실행할 수 있으며 인프라가 자동으로 배포됩니다. 폴더model_files
의 모든 파일은 생성한 s3 버킷에 업로드됩니다. Lambda 함수는 Docker를 사용하여 번들로 제공되며 ECR
에 저장됩니다.Lambda 함수 테스트 및 쿼리
테스트는 모델에 따라 다릅니다. 시작하기에 충분한 개요를 알려드렸기를 바랍니다. 새로 배포된 Lambda 함수로 데이터를 보내려면 CDK 배포가 완료된 후의 출력 또는 AWS Lambda 콘솔에서 함수 URL을 찾을 수 있습니다.
아래에 표시된 데이터는 "hello!"입니다. - 당신에게는 무엇이든 될 수 있습니다. 예를 들어 내 모델은 값 목록을 받습니다.
완료되면 요금이 부과되지 않도록
cdk destroy
를 확인하십시오!이 기사가 Lambda를 사용하여 신경망 또는 기타 기계 학습 알고리즘을 배포하는 데 좋은 출발점이 되었기를 바랍니다.
Reference
이 문제에 관하여(AWS Lambda, Docker 및 AWS CDK를 사용하여 Tensorflow 모델을 생산에 투입), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/wesleycheek/put-a-tensorflow-model-into-production-with-aws-lambda-and-aws-cdk-1jg6텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)