news 2026/2/26 7:01:08

使用 FastAPI、Azure 和 Docker 进行模型部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用 FastAPI、Azure 和 Docker 进行模型部署

原文:towardsdatascience.com/model-deployment-with-fastapi-azure-and-docker-10e5cfbc1f4f

欢迎来到我MLOps 系列文章的第三篇。在 第一篇文章 中,我们探讨了 Docker 以及它是如何简化应用程序打包的。在 第二篇文章 中,我们使用MLflowAzureDocker管理机器学习模型。现在,在这一部分的第三部分,我们将通过构建一个FastAPI应用程序来整合所有内容,该应用程序在 Azure 上为我们之前存储的模型提供服务。这使我们能够创建一个全球可访问的预测服务!

什么是 API?

API就像一座桥梁。每次你与 Python 中的库交互时,你都在使用它的 API。它是你可以与之交互的应用程序公开部分,而其背后的所有内容都是隐藏的。

API 通常用于与 Web 应用程序通信,并提供一组返回数据的 URL(你发送带有一些参数的请求并得到响应)。最常见的是,数据以 JSON 或 XML 等易于解析的格式返回。这与返回 HTML 的网站不同,HTML 包含用于渲染页面的信息。使用 API,你只得到原始数据。

一些 API 是公开的,而另一些则是私有的。在构建 API 时,你决定要共享哪些数据,如何共享,以及与谁共享。一切由你决定!大多数 API 使用 HTTP 协议进行通信。你可能听说过遵循共同标准的REST API。主要的 HTTP 方法包括:

  • GET:检索数据。

  • POST:提交新数据。

  • PUT:更新现有数据。

  • DELETE:删除数据。

这些方法形成了几乎每个 API 都遵循的CRUD(创建、读取、更新、删除)操作。

如何请求 API?

既然我们已经知道了什么是 API,让我们尝试调用一个。我们将使用猫事实 API,它以 JSON 格式返回随机的猫事实。

API 附带文档,解释了可用的端点和参数。端点是请求数据的地址(URL 中的路径)。阅读文档是必不可少的,因为它可以节省你以后的时间。

这里有一个使用 Python 的requests库调用 Cat Facts API 的/fact端点的快速示例:

importrequests response=requests.get("https://catfact.ninja/fact").json()print(response)

这个有趣的 API 以 JSON 格式返回关于猫的随机事实:

{'fact':'Cats lap liquid from the underside of their tongue, not from the top.','length':69}

使用requests可以帮助你使用 API,但如果你想要构建一个呢?这就是FastAPI发挥作用的地方。它是构建 API 的最佳框架之一。

FastAPI 基础

有许多 Python 框架可以用于构建 API,但在这个教程中,我选择了FastAPI。它是构建 API 中最好和最简单的框架之一,并且它带有许多实用功能,因此您不需要重新发明轮子:

  • Web 服务器:FastAPI 使用 Uvicorn 为您设置网络服务器。

  • 数据验证:它使用 Pydantic 自动验证数据格式。

  • 自动文档:FastAPI 可以自动生成 API 文档,这使得开发者工作变得非常简单。

您的 FastAPI Python 文件的基本结构

当你使用 FastAPI 构建 API 时,你的.py文件将具有特定的结构,看起来像这样:

importuvicornfromfastapiimportFastAPI#### Here you can define some configurations###app=FastAPI()#### Here you define enpoints###if__name__=="__main__":uvicorn.run(app,host="0.0.0.0",port=8000)
  • app = FastAPI():这创建了一个 FastAPI 实例,它将包含您应用程序的所有功能。

  • if name==“main”:这确保了当直接执行此文件而不是将其作为模块导入时,代码块才会运行。

  • uvicorn.run(app, host=“0.0.0.0”, port=8000):这启动了 Uvicorn 网络服务器,指定了主机 IP 和端口。

创建端点

端点是一个 URL,API 用户可以在此处请求或发送数据。我们主要有两种类型:

  1. GET:用于检索数据。

  2. POST:用于发送新数据。

让我们从最简单的可能的GET端点/开始,它将显示一个问候消息:

importuvicornfromfastapiimportFastAPI app=FastAPI()@app.get("/")asyncdefindex():return{"message":"Welcome to the Iris classification API. Use `/predict` to classify a flower."}if__name__=="__main__":uvicorn.run(app,host="0.0.0.0",port=8000)
  • @app.get(“/”):这个装饰器定义了当向/端点发送 GET 请求时,将调用index()函数。

  • async:FastAPI 允许异步操作。异步函数让您更有效地处理请求,尤其是在处理数据库查询等输入/输出任务时。

让我们添加一个POST端点来提交数据:

importuvicornfromfastapiimportFastAPIfrompydanticimportBaseModel app=FastAPI()className(BaseModel):name:str@app.post("/submit")asyncdefsubmit_name(data:Name):return{"message":f"Hello,{data.name}!"}if__name__=="__main__":uvicorn.run(app,host="0.0.0.0",port=8000)
  • 这个POST端点接受用户输入数据。并非所有 API 都接受用户数据,但当他们这样做时,数据需要具有特定的结构,这在Name(BaseModel)类中定义。

使用 Docker 运行 API

为什么使用 Docker?使用 Docker,您不需要在本地机器上安装依赖项。所有内容都在容器中运行,这使得它易于便携和部署。如果您不熟悉 Docker,请查看我之前的文章初学者指南:Docker。

第 1 步:创建一个 Dockerfile

要部署 FastAPI 应用程序,我们首先创建一个 Dockerfile:

# python base image in the container from Docker HubFROM python:3.9-slim RUN apt-get update-y RUN apt-get install nano unzip RUN apt-get install-y python3.10RUN apt install curl-y RUN curl-fsSL https://get.deta.dev/cli.sh|sh# Set the working directoryWORKDIR/app# Copy the current directory contents into the container at /appCOPY./app# Install Python dependencies specified in requirements.txtRUN pip install--no-cache-dir-r requirements.txt# expose the port that uvicorn will run the app onENV PORT=8000EXPOSE8000# execute the command python main.py (in the WORKDIR) to start the app# CMD ["python", "api.py"]CMD["uvicorn","api:app","--host","0.0.0.0","--port","8000"]
  • 这个 Dockerfile 安装所有依赖项,设置工作目录,并使用 Gunicorn 和 Uvicorn 运行应用程序。requirements.txt文件将包含必要的 Python 包,如 FastAPI、Uvicorn 等。

第 2 步:构建和运行 Docker 容器

构建 Docker 镜像:

docker build.-t fastapiserver# if your are on mac, use :# docker build - platform=linux/amd64 -t fastapiserver

运行 Docker 容器:

docker run-it-v"$(pwd):/app"-p8000:8000-e PORT=8000fastapiserver

一旦运行,打开您的浏览器并转到http://0.0.0.0:8000。您应该能看到您的 FastAPI 应用程序正在运行!

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/75d459a33eb8ece3813393b8cce866fe.png

作者

创建一个用于提供 ML 模型的端点

现在,让我们将MLflowFastAPI结合起来,以提供机器学习模型。我们将加载存储在 Azure 中的模型,并创建一个用于进行预测的端点。

到目前为止,你有两个选择:

  1. 你已经遵循了我的上一篇文章,并且你的模型已经序列化并保存在 Azure 中。

  2. 你没有遵循我的上一篇文章。你需要知道的是:我们在 Iris 数据集上训练了一个模型,该模型根据四个特征预测花朵的类型。我们使用MLflow序列化此模型并将其存储在 Azure 中。如果你没有这样做,你可以从这个 GitHub 文件夹下载 model.pkl 文件并将其上传到 Azure Blob 存储。

完成上述步骤后,无论你是处于案例 1 还是案例 2,你都需要检索你的Azure 存储信息,并在以下脚本中替换相关值:

importuvicornimportpandasaspdfromfastapiimportFastAPIfrompydanticimportBaseModelfromazure.storage.blobimportBlobClientimportjoblibimportio# Initialize FastAPIapp=FastAPI()# Define the request body format for predictionsclassPredictionFeatures(BaseModel):sepal_length:floatsepal_width:floatpetal_length:floatpetal_width:float# Global variable to store the loaded modelmodel=None# Download the model from Azure Blob Storage directly into memorydefdownload_model():globalmodel# If you want to follow the tutorial but don't have an azure account, just load the model directly from the local file# model = joblib.load("path_to_your_local_model/model.pkl")blob=BlobClient(account_url="https://<your-storage-account>.blob.core.windows.net/",container_name="<your-container>",blob_name="model.pkl",credential="<your-storage-key>")# Download the model as a stream of bytesstream=io.BytesIO()blob.download_blob().download_to_stream(stream)# Load the model directly from the in-memory streamstream.seek(0)model=joblib.load(stream)print("Model loaded from Azure Blob Storage successfully!")# Download the model immediately when the script runsdownload_model()# API Root endpoint@app.get("/")asyncdefindex():return{"message":"Welcome to the Iris classification API. Use `/predict` to classify a flower."}# Prediction endpoint@app.post("/predict")asyncdefpredict(features:PredictionFeatures):# Create input DataFrame for predictioninput_data=pd.DataFrame([{"sepal length (cm)":features.sepal_length,"sepal width (cm)":features.sepal_width,"petal length (cm)":features.petal_length,"petal width (cm)":features.petal_width}])# Predict using the loaded modelprediction=model.predict(input_data)# Get the class number (0, 1, or 2)class_index=int(prediction[0])# Get the class name from the class indexclass_names=['setosa','versicolor','virginica']class_name=class_names[class_index]return{"prediction":class_index,"class_name":class_name}if__name__=="__main__":uvicorn.run(app,host="0.0.0.0",port=8000)
  • download_model()函数从 Azure Blob 存储检索模型并将其加载到内存中。

  • 根端点/提供了一个欢迎信息。

  • /predict端点仍然存在,允许用户将花朵测量值作为 JSON 数据发送给模型以获取预测。

  • 在此脚本中,class用于定义用户必须发送到/predict端点的数据结构。在 FastAPI 中这很重要,因为它有助于验证用于预测的传入数据。

本地测试 API

重新构建并运行你的 Docker 容器,然后访问http://0.0.0.0:8000。使用以下 Python 脚本测试预测端点:

importrequests# Define the API endpointurl="http://0.0.0.0:8000/predict"# Define the input datadata={"sepal_length":5.1,"sepal_width":3.5,"petal_length":1.4,"petal_width":0.2}# Make a POST request to the APIresponse=requests.post(url,json=data)# Check if the request was successfulifresponse.status_code==200:# Print the prediction resultprediction=response.json()print("Prediction:",prediction)else:print(f"Failed to get a prediction. Status code:{response.status_code}")print("Response:",response.text)

这将根据输入数据返回预测的花朵分类。我们的花朵属于类别 0,即**-setosa**。

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/53c964fe87ce680fef3ca406a386f45a.png

作者

这听起来不错,但这里有个问题:我们的 API 目前仅在本地上可用。如果有人在世界另一端想要用它来预测他们花朵的分类怎么办?你猜对了——我们需要将这个 API 部署到云端。让我们将其部署到 Azure,这样全世界的花迷都可以使用它!

将 FastAPI 部署到 Azure

在开始之前,确保你准备好了订阅 ID和其他相关细节。你可以从 Azure 门户中获取这些信息。接下来,从我的 GitHub克隆必要的文件,并更新deploy.sh脚本。

更新完信息后,只需运行deploy.sh脚本即可自动化整个设置过程。虽然 Azure 提供了图形界面来设置资源,但此脚本通过单个命令简化了所有操作。

下面是运行deploy.sh脚本时你正在做的事情的分解:

1. 登录并设置订阅:首先,登录到你的 Azure 账户,并设置资源部署的订阅。

az login az accountset--subscription $SUBSCRIPTION_ID

2. 创建资源组:此组将组织您为 FastAPI 部署的所有资源。如果您已经有了资源组,您可以跳过此步骤或在脚本中将其注释掉。

az group create--name $RG_NAME--location<location>

3. 将 Docker 镜像推送到 Azure 容器注册库(ACR):在推送 Docker 镜像之前,获取您的 ACR 凭证并登录。

export ACR_USERNAME=$(az acr credential show--name $ACR_NAME--query"username"--output tsv)export ACR_PASSWORD=$(az acr credential show--name $ACR_NAME--query"passwords[0].value"--output tsv)docker login $ACR_NAME.azurecr.io--username"$ACR_USERNAME"--password"$ACR_PASSWORD"
# Push the imagesdocker tag $DOCKER_IMAGE_NAME $ACR_NAME.azurecr.io/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG docker push $ACR_NAME.azurecr.io/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG

4. 创建应用服务计划:设置应用服务计划以在 Azure 上托管您的 FastAPI 服务器。

az appservice plan create--name $ASP_NAME--resource-group $RG_NAME--sku B1--is-linux--location $RG_LOCATION

5. 使用 FastAPI 容器部署 Web 应用:将 ACR 中的 Docker 镜像部署到您的 Web 应用。

az webapp create--resource-group $RG_NAME--plan $ASP_NAME--name $WEB_APP_NAME--deployment-container-image-name $ACR_NAME.azurecr.io/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG

6. 配置 Web 应用以使用容器注册库:设置应用以拉取 Docker 镜像,并配置环境变量。

az webapp config containerset--name $WEB_APP_NAME--resource-group $RG_NAME--docker-custom-image-name $ACR_NAME.azurecr.io/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG--docker-registry-server-url https://$ACR_NAME.azurecr.io--docker-registry-server-user $ACR_USERNAME--docker-registry-server-password $ACR_PASSWORD--enable-app-service-storage true az webapp config appsettingsset--resource-group $RG_NAME--name $WEB_APP_NAME--settings WEBSITES_PORT=$MLFLOW_PORT

部署脚本完成后,检查 Azure 门户以确认您的 API 已上线并可访问。导航到应用服务以获取您已部署的 FastAPI Web 应用的 URL。

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/8c966f99f35170c776009b733e99bb71.png

作者提供

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/4c8a178092a258b06a0bcdef87396656.png

作者提供

恭喜!您的 API 现在已上线,世界上任何地方的人都可以使用它来根据特征对花卉进行分类。

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/76bd57ed40adc12bc7aa156f4ebee49f.png

作者提供

最终测试:访问已部署的 API

让我们使用与之前相同的 Python 请求脚本来测试已部署的 API,但这次将本地 URL 替换为 Azure 的实际 URL。您应该能看到返回的预测结果!

结论

这篇文章到此结束。您已成功将 FastAPI 应用部署到 Azure,并且它准备好为任何拥有花卉数据的人提供服务。在本系列的下一部分,我们将通过添加文档、单元测试,以及使用CI/CDGitHub Actions自动化部署来改进 API。敬请期待!

感谢您的阅读!

***注意:*某些部分的文章最初是用法语撰写的,并在 ChatGPT 的帮助下翻译成英语。

如果您觉得这篇文章信息丰富且有帮助,请毫不犹豫地👏并关注我在Medium | LinkedIn上的账号。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/21 13:44:48

STM32CubeMX安装失败原因全面讲解

STM32CubeMX装不上&#xff1f;别急着重装系统——这根本不是“安装失败”&#xff0c;而是你和整个嵌入式开发栈在对话刚拿到新电脑&#xff0c;双击STM32CubeMX.exe&#xff0c;弹出一句冷冰冰的“Java not found”&#xff1b;或者点开安装包&#xff0c;进度条卡在 78%&…

作者头像 李华
网站建设 2026/2/14 21:23:17

LLaVA-v1.6-7B新功能体验:672x672高清图像识别实测

LLaVA-v1.6-7B新功能体验&#xff1a;672x672高清图像识别实测 最近试用了刚上线的llava-v1.6-7b镜像&#xff0c;第一反应是——这次真的不一样了。不是参数翻倍那种“纸面升级”&#xff0c;而是实实在在能感觉到图像理解能力变强了&#xff1a;以前看不清的细节现在能认出来…

作者头像 李华
网站建设 2026/2/22 15:26:38

低功耗边缘计算设备电路设计:实战案例

低功耗边缘计算设备电路设计&#xff1a;从CR2032驱动AI推理的实战手记你有没有试过&#xff0c;把一块CR2032纽扣电池焊在PCB上&#xff0c;然后让这颗小电池——230mAh、直径20mm、厚3.2mm——支撑一个能听懂跌倒声、识别人体红外特征、还能跑TinyML模型的边缘节点&#xff0…

作者头像 李华
网站建设 2026/2/19 18:59:31

Qwen-Image-Layered实战应用:电商主图修改超方便

Qwen-Image-Layered实战应用&#xff1a;电商主图修改超方便 你有没有遇到过这样的场景&#xff1a; 刚上新一款防晒霜&#xff0c;主图已经拍好——模特手持产品、背景干净、光线柔和。但运营突然说&#xff1a;“把右下角的‘SPF50’换成‘全波段防护’&#xff0c;再加个蓝…

作者头像 李华
网站建设 2026/2/18 17:27:40

从零开始:Multisim Windows 11版本安装示例

Multisim在Windows 11上装不起来?别点“下一步”了,先看懂这四个底层关卡 你是不是也遇到过:下载完Multisim安装包,双击运行,刚点“下一步”,弹出一个红色错误框——“无法验证发布者”、“安装服务未响应”、“许可证激活失败”……然后就卡住了? 不是你的电脑太老,也…

作者头像 李华
网站建设 2026/2/23 18:50:14

边缘设备也能跑大模型?GLM-4.6V-Flash-WEB实测可行

边缘设备也能跑大模型&#xff1f;GLM-4.6V-Flash-WEB实测可行 你有没有试过在一台RTX 4060笔记本上&#xff0c;不连外网、不装Git、不编译CUDA、不折腾conda环境&#xff0c;只点一下脚本&#xff0c;就让一个支持图文理解的视觉大模型在本地网页里跑起来&#xff1f; 这不…

作者头像 李华