使用FastAPI、AWS Lambda和AWS CDK部署大型语言模型的无服务器ML推理端点

对于数据科学家而言,将机器学习(ML)模型从概念验证转移到生产环境通常是一个重大挑战。其中一个主要挑战可能是将性能良好的本地训练模型部署到云端进行推断并在其他应用程序中使用。管理这个过程可能会很繁琐,但是使用正确的工具,可以显著减少所需的工作量。

Amazon SageMaker 推断在2022年4月正式发布,使您能够轻松将ML模型部署到生产环境中,以便在规模上进行预测,提供广泛的ML基础设施和模型部署选项,以帮助满足各种ML推断需求。您可以使用SageMaker Serverless 推断端点处理在流量突发间隙期间具有空闲时间并且能够容忍冷启动的工作负载。端点会根据流量自动扩展,并消除选择和管理服务器的毫无差异的繁重工作。此外,您还可以直接使用AWS Lambda公开您的模型,并使用您选择的开源框架部署您的ML应用程序,这可能更加灵活和成本效益。

FastAPI 是一种用于使用 Python 构建 API 的现代高性能 Web 框架。在开发 RESTful 微服务和需要在多个行业范围内规模化进行ML推断的用例时,它非常出色。它的易用性和内置功能,如自动API文档,使其成为ML工程师部署高性能推断API的热门选择。您可以使用FastAPI中的开箱即用功能定义和组织路由,根据需要扩展和处理不断增长的业务逻辑,本地测试并在Lambda上托管,然后通过单个API网关公开它,这使您可以将开源Web框架带入Lambda,无需任何重复的工作或重新构建代码。

本文向您展示如何使用FastAPI,Docker,Lambda和Amazon API Gateway将您的ML模型公开为端点以轻松部署和运行无服务器ML推断。我们还向您展示如何使用AWS Cloud Development Kit(AWS CDK)自动化部署。

解决方案概述

以下图表显示了我们在本文中部署的解决方案的体系结构。

先决条件

你必须满足以下的先决条件:

  • 已安装Python3,以及用于在Python中创建和管理虚拟环境的virtualenv
  • 在您的系统上安装了aws-cdk v2,以便使用AWS CDK CLI
  • 已安装并在本地计算机上运行Docker

检查是否安装了所有必要的软件:

  1. 需要AWS命令行界面(AWS CLI)。登录您的帐户并选择要部署解决方案的区域。

  2. 使用以下代码检查Python版本:

    python3 --version
  3. 检查是否已安装用于在Python中创建和管理虚拟环境的virtualenv。严格来说,这不是硬性要求,但它可以使您的生活更轻松,并有助于更轻松地跟随本文。使用以下代码:

    python3 -m virtualenv --version
  4. 检查是否已安装cdk。这将用于部署我们的解决方案。

    cdk --version
  5. 检查是否已安装Docker。我们的解决方案将通过Docker映像使您的模型可通过Lambda访问。为了在本地构建此映像,我们需要Docker。

    docker --version
  6. 确保Docker正在运行并使用以下代码:

    docker ps

如何使用AWS CDK构建FastAPI项目结构

我们使用以下目录结构来表示我们的项目(忽略了在本文内容上下文中不重要的一些AWS CDK样板代码):

```

fastapi_model_serving
│
└───.venv
│
└───fastapi_model_serving
│   │   __init__.py
│   │   fastapi_model_serving_stack.py
│   │
│   └───model_endpoint
│       └───docker
│       │      Dockerfile
│       │      serving_api.tar.gz
│
│
│       └───runtime
│            └───serving_api
│                    requirements.txt
│                    serving_api.py
│                └───custom_lambda_utils
│                     └───model_artifacts
│                            ...
│                     └───scripts
│                            inference.py
│
└───templates
│   └───api
│   │     api.py
│   └───dummy
│         dummy.py
│
│ app.py
│   cdk.json
│   README.md
│   requirements.txt
│   init-lambda-code.sh

```

该目录遵循了 AWS CDK Python 项目的推荐结构。

该存储库最重要的部分是 fastapi_model_serving 目录。它包含了定义 AWS CDK stack 和用于模型服务的资源的代码。

fastapi_model_serving 目录包含 model_endpoint 子目录,该子目录包含组成我们无服务器端点的所有必要资产,即用于构建 Lambda 将使用的 Docker 镜像的 Dockerfile、使用 FastAPI 处理推理请求并将其路由到正确端点的 Lambda 函数代码以及我们要部署的模型的模型工件。 model_endpoint 还包含以下内容:

  • Docker – 此子目录包含以下内容:
  • Dockerfile – 用于构建 Lambda 函数的镜像,镜像中包含所有资产(Lambda 函数代码、模型工件等),以便它们可以无问题地使用。
  • serving.api.tar.gz – 这是一个 tarball,其中包含从 runtime 文件夹中提取的所有资产,这些资产对于构建 Docker 镜像是必要的。我们将在本文中讨论如何创建 .tar.gz 文件。
  • runtime – 此子目录包含以下内容:
  • serving_api – Lambda 函数的代码和 requirements.txt 文件中指定的依赖项。
  • custom_lambda_utils – 这包括一个推理脚本,加载所需的模型工件,以便将模型传递给 serving_api,然后将其公开为端点。

此外,还有模板目录,该目录提供了一个文件夹结构和文件的模板,您可以根据我们之前介绍的样本定义自定义代码和 API。模板目录包含您可以使用其创建新的 Lambda 函数的虚拟代码:

  • dummy – 包含实现使用 Python 运行时实现普通 Lambda 函数结构的代码
  • api – 包含实现将 FastAPI 端点封装到现有 API 网关周围的 Lambda 函数的代码

部署解决方案

默认情况下,该代码在 eu-west-1 区域内部署。如果您想更改区域,则可以更改 cdk.json 文件中的 DEPLOYMENT_REGION 上下文变量。

请记住,该解决方案尝试在 arm64 架构之上部署 Lambda 函数,而此功能可能不在所有区域可用。在这种情况下,您需要更改 fastapi_model_serving_stack.py 文件中的架构参数,以及 Docker 目录中的 Dockerfile 的第一行,以在 x86 架构上托管此解决方案。

要部署解决方案,请执行以下步骤:

  1. 运行以下命令以克隆 GitHub 存储库:git clone https://github.com/aws-samples/lambda-serverless-inference-fastapi。因为我们想展示该解决方案可以处理您在本地训练的模型工件,所以我们在 serving_api.tar.gz 文件中包含了预训练 DistilBERT 模型的示例模型工件,该模型工件存储在 Hugging Face 模型中心。下载时间可能需要大约 3-5 分钟。现在,让我们设置环境。

  2. 将将要部署的预训练模型从 Hugging Face 模型中心下载到 ./model_endpoint/runtime/serving_api/custom_lambda_utils/model_artifacts 目录中。它还创建了一个虚拟环境并安装了所有所需的依赖项。您只需要运行此命令一次:make prep。此命令可能需要大约 5 分钟(取决于您的互联网带宽),因为它需要下载模型工件。

  3. 将模型工件打包到一个 .tar.gz 存档中,该存档将用于 AWS CDK 堆栈中构建的 Docker 镜像。每当您更改模型工件或 API 本身时,都需要运行此代码,以始终具有您的服务端点的最新版本:make package_model。所有工件都已就绪。现在,我们可以将 AWS CDK 堆栈部署到您的 AWS 帐户。

  4. 如果这是您第一次将 AWS CDK 应用程序部署到环境中(帐户+区域组合),请运行 cdk bootstrap:

    make cdk_bootstrap

    此堆栈包括工具包操作所需的资源。例如,该堆栈包括用于在部署过程中存储模板和资产的 Amazon 简单存储服务(Amazon S3)存储桶。

    由于我们在此 AWS CDK 部署中本地构建 Docker 镜像,因此我们需要确保在部署此堆栈之前 Docker 守护程序正在运行。

  5. 要检查 Docker 守护程序是否在您的系统上运行,请使用以下命令:

    docker ps

    如果您没有收到错误消息,则应准备好部署解决方案。

  6. 使用以下命令部署解决方案:

    make deploy

    由于要构建和推送 Docker 镜像,因此此步骤可能需要大约 5-10 分钟。

故障排除

如果您是Mac用户,使用Docker登录Amazon Elastic Container Registry(Amazon ECR)时可能会遇到错误,例如Error saving credentials ... not implemented 。例如:

exited with error code 1: Error saving credentials: error storing credentials - err: exit status 1,...dial unix backend.sock: connect: connection refused

在您可以在AWS CDK中使用基于Docker容器的Lambda之前,您可能需要更改~/docker/config.json文件。更具体地说,您可能需要将~/.docker/config.json中的credsStore参数更改为osxkeychain。这解决了Mac上的Amazon ECR登录问题。

运行实时推理

成功部署AWS CloudFormation堆栈后,转到AWS CloudFormation控制台上堆栈的输出选项卡并打开端点URL。现在我们的模型可以通过端点URL访问,我们准备运行实时推理。

导航到URL以查看是否可以看到“hello world”消息,并将/docs添加到地址中以查看是否可以成功查看交互式swagger UI页面。可能会有一些冷启动时间,因此您可能需要等待或刷新几次。

登录FastAPI swagger UI页面的登陆页后,可以通过根/或通过/question运行。

/中,您可以运行API并获得“hello world”消息。

/question中,您可以运行API并对我们为问答案例部署的模型进行ML推理。例如,我们使用的问题是“What is the color of my car now?”,上下文是“My car used to be blue but I painted red”。

当您选择执行时,根据给定的上下文,模型将用响应回答问题,如下图所示。

在响应正文中,您可以看到模型的置信度得分和答案。您还可以尝试其他示例或将API嵌入到现有应用程序中。

或者,您可以通过代码运行推理。这里是一个使用requests库编写的Python示例:

import requests

url = "https://<YOUR_API_GATEWAY_ENDPOINT_ID>.execute-api.<YOUR_ENDPOINT_REGION>.amazonaws.com/prod/question?question=\"What is the color of my car now?\"&context=\"My car used to be blue but I painted red\""

response = requests.request("GET", url, headers=headers, data=payload)

print(response.text)

代码输出类似于以下内容的字符串:

'{"score":0.6947233080863953,"start":38,"end":41,"answer":"red"}'

如果您想了解有关在AWS上部署生成AI和大型语言模型的更多信息,请查看以下内容:

  • 使用OpenLLaMa在AWS Lambda上部署无服务器生成AI
  • 使用大型模型推理容器在AWS Inferentia2上部署大型语言模型

清理

在存储库的根目录中,运行以下代码来清理您的资源:

make destroy

结论

在本文中,我们介绍了如何使用Lambda来部署已训练好的ML模型,使用您喜欢的Web应用程序框架,例如FastAPI。我们提供了一个详细的代码库,您可以部署它,并保留切换到任何已处理的训练模型工件的灵活性。性能取决于您如何实现和部署模型。

欢迎您自己尝试,并且我们很高兴听到您的反馈!