假設您正在進行一個機器學習( ML )項目,并且已經找到了您的冠軍模型。接下來會發生什么?對許多人來說,項目就此結束,他們的模型被隔離在 Jupyter 筆記本中。其他人會主動將筆記本轉換為腳本,以獲得某種生產級代碼。
這兩個端點都限制了項目的可訪問性,需要了解 GitHub 和 Bitbucket 等托管源代碼的站點。一個更好的解決方案是將您的項目轉換為一個可以部署在內部服務器上的前端原型。
雖然原型可能不是生產標準,但它是公司用來為利益相關者提供建議解決方案洞察力的有效技術。這樣,公司就可以收集反饋,并在未來開發更好的迭代。
要開發原型,您需要:
- 用戶交互的前端
- 可以處理請求的后端
然而,這兩個需求都需要花費大量的時間來構建。在本教程中,您將學習如何使用 Streamlit 為前端和 FastAPI 為微服務快速構建自己的機器學習 web 應用程序,從而簡化流程。在 Building a Machine Learning Microservice with FastAPI 中了解有關微服務的更多信息。
您可以使用 kurtispykes/car-evaluation-project GitHub 存儲庫中的代碼嘗試本教程中的應用程序。
Streamlit 和 FastAPI 概述
Streamlit 是一個開源應用程序框架,旨在簡化為機器學習和數據科學構建 web 應用程序的過程。近年來,它在應用 ML 社區中獲得了很大的吸引力。 Streamlit 成立于 2018 年,是前谷歌工程師在部署機器學習模型和儀表盤時遇到的挑戰所帶來的挫折。
使用 Streamlit 框架,數據科學家和機器學習實踐者可以在幾個小時內構建自己的預測分析 web 應用程序。不需要依賴前端工程師或 HTML 、 CSS 或 Javascript 知識,因為這一切都是用 Python 完成的。
FastAPI 在 Python 開發商中也迅速崛起。這是一個現代的網絡框架,也于 2018 年首次發布,旨在彌補 Flask 幾乎所有失敗的領域。切換到 FastAPI 的一個好處是學習曲線不是很陡,特別是如果你已經知道 Flask 。有了 FastAPI ,您可以期待完整的文檔、短的開發時間、簡單的測試和輕松的部署。這使得在 Python 中開發 RESTful API 成為可能。
通過結合這兩個框架的強大功能,您可以在不到一天的時間內開發一個激動人心的機器學習應用程序,與您的朋友、同事和利益相關者共享。
構建全棧機器學習應用程序
以下步驟指導您使用 FastAPI 和 Streamlit 構建簡單的分類模型。該模型根據以下六個輸入特征評估汽車是否可以接受:
buying
: 購車成本maint
:維護成本doors
:門的數量persons
:承載能力(人數)lug_boot
: The size of the luggage bootsafety
:估計的安全性
您可以從 UCI machine learning repository 下載完整的 Car Evaluation 數據集。
完成所有數據分析、培訓冠軍模型并打包機器學習模型后,下一步是創建兩個專用服務: 1 ) FastAPI 后端和 2 ) Streamlit 前端。然后,這兩個服務可以部署在兩個 Docker 容器中,并使用 Docker Compose 進行編排。
每個服務都需要自己的 Dockerfile 來組裝 Docker 映像。定義和共享兩個容器應用程序還需要 Docker Compose YAML 文件。以下步驟貫穿于每個服務的開發。
用戶界面
在car_evaluation_streamlit
包中,使用 Streamlit 在app.py
文件中創建一個簡單的用戶界面。以下代碼包括:
- UI 的標題
- 項目簡介
- 用戶將使用六個交互元素輸入有關汽車的信息
- API 返回的類值
- 一個提交按鈕,單擊該按鈕時,將把從用戶收集的所有數據作為 post 請求發送到機器學習 API 服務,然后顯示模型的響應
import requests
import streamlit as st
# Define the title
st.title("Car evaluation web application")
st.write(
"The model evaluates a cars acceptability based on the inputs below.\
Pass the appropriate details about your car using the questions below to discover if your car is acceptable."
)
# Input 1
buying = st.radio(
"What are your thoughts on the car's buying price?",
("vhigh", "high", "med", "low")
)
# Input 2
maint = st.radio(
"What are your thoughts on the price of maintenance for the car?",
("vhigh", "high", "med", "low")
)
# Input 3
doors = st.select_slider(
"How many doors does the car have?",
options=["2", "3", "4", "5more"]
)
# Input 4
persons = st.select_slider(
"How many passengers can the car carry?",
options=["2", "4", "more"]
)
# Input 5
lug_boot = st.select_slider(
"What is the size of the luggage boot?",
options=["small", "med", "big"]
)
# Input 6
safety = st.select_slider(
"What estimated level of safety does the car provide?",
options=["low", "med", "high"]
)
# Class values to be returned by the model
class_values = {
0: "unacceptable",
1: "acceptable",
2: "good",
3: "very good"
}
# When 'Submit' is selected
if st.button("Submit"):
# Inputs to ML model
inputs = {
"inputs": [
{
"buying": buying,
"maint": maint,
"doors": doors,
"persons": persons,
"lug_boot": lug_boot,
"safety": safety
}
]
}
# Posting inputs to ML API
response = requests.post(f"http://host.docker.internal:8001/api/v1/predict/", json=inputs, verify=False)
json_response = response.json()
prediction = class_values[json_response.get("predictions")[0]]
st.subheader(f"This car is **{prediction}!**")
此服務所需的唯一框架是 Streamlit 。在requirements.txt
文件中,注意創建 Docker 映像時要安裝的 Streamlit 版本。
streamlit>=1.12.0, <1.13.0
現在,添加 Dockerfile 以創建此服務的 docker 映像:
FROM python:3.9.4
WORKDIR /opt/car_evaluation_streamlit
ADD ./car_evaluation_streamlit /opt/car_evaluation_streamlit
RUN pip install --upgrade pip
RUN pip install -r /opt/car_evaluation_streamlit/requirements.txt
EXPOSE 8501
CMD ["streamlit", "run", "app.py"]
每個命令創建一個層,每個層都是一個圖像。
REST API
Representational State Transfer Application Programming Interfaces ( REST API )是一種使兩個應用程序能夠相互通信的軟件架構。從技術上講, REST API 將被請求資源的狀態傳輸給客戶端。在這種情況下,請求的資源將是機器學習模型的預測。
使用 FastAPI 構建的 API 可以在car_evaluation_api
包中找到。找到用于運行應用程序的app/main.py
文件。有關如何開發 API 的更多信息,請參閱 Building a Machine Learning microservice with FastAPI 。
from typing import Any
from fastapi import APIRouter, FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import HTMLResponse
from loguru import logger
from app.api import api_router
from app.config import settings, setup_app_logging
# setup logging as early as possible
setup_app_logging(config=settings)
app = FastAPI(
title=settings.PROJECT_NAME, openapi_url=f"{settings.API_V1_STR}/openapi.json"
)
root_router = APIRouter()
@root_router.get("/")
def index(request: Request) -> Any:
"""Basic HTML response."""
body = (
"<html>"
"<body style='padding: 10px;'>"
"<h1>Welcome to the API</h1>"
"<div>"
"Check the docs: <a href='/docs'>here</a>"
"</div>"
"</body>"
"</html>"
)
return HTMLResponse(content=body)
app.include_router(api_router, prefix=settings.API_V1_STR)
app.include_router(root_router)
# Set all CORS enabled origins
if settings.BACKEND_CORS_ORIGINS:
app.add_middleware(
CORSMiddleware,
allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
if __name__ == "__main__":
# Use this for debugging purposes only
logger.warning("Running in development mode. Do not run like this in production.")
import uvicorn
uvicorn.run(app, host="localhost", port=8001, log_level="debug")
上面的代碼定義了服務器,它包括三個端點:
"/"
:用于定義返回 HTML 響應的主體的端點"/health"
:返回模型健康響應模式的端點"/predict"
:用于服務于訓練模型預測的端點
您可能在上面的代碼中只能看到"/"
端點:這是因為"/health"
和"/predict"
端點是從 API 模塊導入并添加到應用程序路由器的。
接下來,將 API 服務的依賴項保存在requirements.txt
文件中:
--extra-index-url="https://repo.fury.io/kurtispykes/"
car-evaluation-model==1.0.0
uvicorn>=0.18.2, <0.19.0
fastapi>=0.79.0, <1.0.0
python-multipart>=0.0.5, <0.1.0
pydantic>=1.9.1, <1.10.0
typing_extensions>=3.10.0, <3.11.0
loguru>=0.6.0, <0.7.0
注意: pip 中添加了一個額外的索引來安裝 Gemrafre 的打包模型。
接下來,將 Dockerfile 添加到car_evalutation_api
包中。
FROM python:3.9.4
# Create the user that will run the app
RUN adduser --disabled-password --gecos '' ml-api-user
WORKDIR /opt/car_evaluation_api
ARG PIP_EXTRA_INDEX_URL
# Install requirements, including from Gemfury
ADD ./car_evaluation_api /opt/car_evaluation_api
RUN pip install --upgrade pip
RUN pip install -r /opt/car_evaluation_api/requirements.txt
RUN chmod +x /opt/car_evaluation_api/run.sh
RUN chown -R ml-api-user:ml-api-user ./
USER ml-api-user
EXPOSE 8001
CMD ["bash", "./run.sh"]
這兩個服務都已經創建,以及為每個服務構建容器的說明。
下一步是將容器連接在一起,以便開始使用機器學習應用程序。繼續之前,請確保已安裝 Docker 和 Docker Compose 。如有必要,請參考 Docker Compose installation guide 。
連接 Docker 容器
要將容器連接在一起,請在 packages/
directory.
Docker Compose 文件的內容如下:
version: '3'
services:
car_evaluation_streamlit:
build:
dockerfile: car_evaluation_streamlit\Dockerfile
ports:
- 8501:8501
depends_on:
- car_evaluation_api
car_evaluation_api:
build:
dockerfile: car_evaluation_api\Dockerfile
ports:
- 8001:8001
該文件定義了要使用的 Docker Compose 版本,定義了要連接在一起的兩個服務、要公開的端口以及到各自 Dockerfiles 的路徑。請注意,car_evaluation_streamlit
服務通知 Docker Compose 它依賴于car_evaluation_api
服務。
要測試應用程序,請從命令提示符(docker-compose.yml
文件的位置)導航到項目根目錄。然后運行以下命令來構建圖像并啟動兩個容器:
docker-compose up -d --build
構建圖像可能需要一兩分鐘。構建 Docker 映像后,您可以導航到 http://localhost:8501 以使用該應用程序。

圖 1 顯示了本文開頭概述的六個模型輸入:
- 購車價格(低、中、高、非常高)
- 汽車的維護成本(低、中、高、非常高)
- 汽車的門數( 2 、 3 、 4 、 5 +)
- 汽車可運載的乘客數量( 2 、 4 或更多)
- 行李箱的大小(小、中、大)。
- 汽車的預期安全性(低、中、高)
總結
祝賀您剛剛創建了自己的全棧機器學習 web 應用程序。接下來的步驟可能涉及使用 Heroku Cloud 、 Google App Engine 或 Amazon EC2 等服務在 web 上部署應用程序。
Streamlit 使開發人員能夠為數據科學和機器學習快速構建美觀的用戶界面。開始使用 Streamlit 所需的全部工作知識就是 Python 。 FastAPI 是一個現代網絡框架,旨在彌補燒瓶掉落的大部分區域。您可以同時使用 Streamlit 和 FastAPI 后端,使用 Docker 和 Docker Compose 構建一個全棧 web 應用程序。
?