机器学习模型部署之 FastAPI 速成
本文中,云朵君将和大家一起学习FastAPI,我们可以使用了FastAPI将机器学习模型部署为API。
-
首先,关键优势之一是速度;FastAPI使用pydantic进行数据验证,Starlette进行工具化。这使得FastAPI的性能与Node或Go相当。 -
其次,它还支持开箱即用的异步模式。这意味着你可以同时运行coroutines,如果按顺序运行,这将大大减少执行时间。 -
第三,FastAPI有很好的开发体验,因为它感觉像Flask这样的轻量级库。 -
第四,它带有开箱即用的OpenAPI文档,使前端团队更容易与API集成。我已经使用FastAPI很长时间了。通常情况下,我得到的前端开发人员比其他框架少,因为我为他们提供了FastAPI自动生成的文档。 -
最后,它给你提供了广泛的、例子丰富的文档。我不记得我最后一次在FastAPI文档(主要是Stackoverflow)之外查找东西来实现某个功能。
考虑到这一点,我们用FastAPI写一个最小的例子,了解如何用FastAPI部署任何机器学习模型。
学习目标
学习完本章后,我们不应该能够独立完成:
-
用FastAPI部署机器学习模型 -
了解使用FastAPI的基础知识 -
用pydantic轻松进行数据验证
创建一个简单的推理API
我们将从一个简单的推理API开始,并将我们的模型相关的东西(序列化的模型文件、测试、预处理文件等等)放在一个叫做ml的模块中。我们不会为我们的简单模型维护任何测试,但这是你在创建机器学习推理API时应该遵循的结构。以下将是我们文件夹的结构。
在我们的API模块中,我们有主文件和一个包含测试的ml文件夹,
model.py
为API加载模型。现在我们先查看
model.py
。
下面是这个文件中的代码。
# model.py
MALE_WORDS = ['he', 'him', 'his']
FEMALE_WORDS = ['she', 'her']
min_length = 10
def preprocess(text): return text.lower().split(' ')
def predict(text):
m = 0
f = 0
preprocessed = preprocess(text)
for word in MALE_WORDS:
if word.lower() in preprocessed:
m += 1
for word in FEMALE_WORDS:
if word.lower() in preprocessed:
f += 1
return {
"gender_content": {
"male": m/(m+f) if (m+f) != 0 else 0,
"female": f/(m+f) if (m+f) != 0 else 0
},
"text_processed": preprocessed,
}
这是一个简单的模型,根据某些关键词获得男性和女性的百分比。我还提到了文本的
min_length
作为一个输入约束。我们将在后面看到我们如何为我们的输入强制执行这个约束。
这一点很重要,因为当从用户那里获得输入时,必须确保我们以适当的格式获得输入,可以用
pydantic
轻松地执行这一点。
这个模型很简单。它通过空间分割文本来进行标记,然后检查简单模型中存在的所有男性/女性词汇。然后,它返回男性、女性的内容以及预处理的文本。所以,现在进入
main.py
文件,检查里面的代码是什么。
from fastapi import FastAPI
from .ml.model import predict, min_length
@app.get("/")
def health():
return {"message": "API is working"}
@app.post("/predict")
def predict_gender_content(text: str):
resp = predict(text)
return resp
这就是创建具有完整文档支持(通过OpenAPI)的API的简单程度。我们得到预测函数并创建一个
@app.post
路由,用于获取文本并返回响应。注意,要运行这个程序,需要安装
uvicorn
并输入“
uvicorn api.main:app –reload
”。
看看是如何查找文档的:
我们可以看到一个文本参数作为输入,现在可以用任何文本来测试该模型。
但是最小文本长度怎么办?我们怎样才能将其纳入呢?一种方法是在预测端点检查输入长度,当它不满足最小长度时返回错误信息。但是可以通过pydantic验证器做得更好。我们还需要向用户展示输入和输出的适当结构。
定义输入和输出数据结构并处理数据验证
我们直接进入代码,看看处理这个问题有多容易:
# main.py
from typing import Optional, List
from fastapi import FastAPI
from pydantic import BaseModel, validator
from .ml.model import predict, preprocess, min_length
class PredictRequest(BaseModel):
data: str
@validator("data")
def check_length(cls, t):
if len(t) < min_length:
raise ValueError(f"Text is too short! require at least {min_length} characters")
return t
class PredictResponse(BaseModel):
data: dict
app = FastAPI()
@app.get("/")
def health():
return {"message": "API is working"}
@app.post("/predict", response_model=PredictResponse)
def predict_gender_content(input: PredictRequest):
text = input.data
resp = predict(text)
result = PredictResponse(data=resp)
return result
我们定义
PredictRequest
类,该类继承自
pydantic
的
BaseModel
,我们将其定义为一个字符串和一个验证器,用于检查文本是否具有适当的长度。这就是我们对输入数据实施验证的地方。而一般来说,在机器学习中,我们会对数据维度进行验证(比方说,我们正在构建一个预测房价的应用程序,有十个特征;应该检查数据是否包含十个值。我们可以按照这个过程来做,定义一个带有适当验证的
PredictRequest
。我们还定义了一个
PredictResponse
类,定义了输出的结构和修改后的预测路线。
现在,如果传递一个短于10的字符串,那么将得到一个422错误,其信息是在验证器中定义的,如下所示。
无效数据的错误响应
定义请求和响应格式的原因是为了使用户能够很容易地将我们的API与他们的代码集成。
总结
至此,我们结束了对FastAPI的简短介绍。现在,你可以为你的机器学习模型创建一个推理API,并遵循一个适当的结构。首先,我们创建了一个简单的推理API,然后添加输入和适当的数据验证。更多优质内容,请关注和星标公众号 数据STUDIO 。
需要记住的几点
以下是需要记住的几个要点。
-
FastAPI对网络使用starlette,对数据验证使用pydantic。 -
FastAPI拥有开箱即用的async和await。 -
始终从用户那里验证你的输入数据
🏴☠️宝藏级🏴☠️ 原创公众号『 数据STUDIO 』内容超级硬核。公众号以Python为核心语言,垂直于数据科学领域,包括 可戳 👉 Python | MySQL | 数据分析 | 数据可视化 | 机器学习与数据挖掘 | 爬虫 等,从入门到进阶!
长按👇关注- 数据STUDIO -设为星标,干货速递