大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流
个人主页-Sonhhxg_柒的博客_CSDN博客
欢迎各位→点赞 + 收藏⭐️ + 留言
系列专栏 - 机器学习【ML】 自然语言处理【NLP】 深度学习【DL】
foreword
✔说明⇢本人讲解主要包括Python、机器学习(ML)、深度学习(DL)、自然语言处理(NLP)等内容。
如果你对这个系列感兴趣的话,可以关注订阅哟
文章目录
技术要求
fastAPI Transformer 模型服务
Docker 化 API
使用 TFX 提供更快的 Transformer 模型
使用 Locust 进行负载测试
概括
到目前为止,我们已经探索了有关 Transformer 的许多方面,并且您已经学习了如何从头开始训练和使用 Transformer 模型。您还学习了如何针对许多任务对它们进行微调。但是,我们仍然不知道如何在生产中为这些模型提供服务。与任何其他现实生活和现代解决方案一样,基于自然语言处理( NLP ) 的解决方案必须能够在生产环境中提供服务。但是,在开发此类解决方案时,必须考虑响应时间等指标。
本章将解释如何在 CPU/GPU 可用的环境中提供基于 Transformer 的 NLP 解决方案。此处将描述用于机器学习部署的TensorFlow Extended ( TFX ) 作为解决方案。此外,还将说明将 Transformer 作为 API 提供服务的其他解决方案,例如 FastAPI。您还将了解 Docker 的基础知识,以及如何对您的服务进行 docker 化并使其可部署。最后,您将学习如何使用 Locust 对基于 Transformer 的解决方案执行速度和负载测试。
我们将在本章中介绍以下主题:
我们将使用 Jupyter Notebook、Python 和 Dockerfile 来运行我们的编码练习,这需要 Python 3.6.0。需要安装以下软件包:
有很多网络框架我们可以用来服务。Sanic、Flask 和 fastAPI 只是一些示例。然而,fastAPI 最近因其速度和可靠性而备受关注。在本节中,我们将使用 fastAPI 并学习如何根据其文档构建服务。我们还将使用pydantic来定义我们的数据类。让我们开始!
$ pip install pydantic
$ pip install fastapi
我们将为此使用问答( QA ) 模型。正如你从第 6 章,用于标记分类的微调语言模型中知道的那样,输入的形式为一个问题和一个上下文。
from pydantic import BaseModel
class QADataModel(BaseModel):
question: str
context: str
from transformers import pipeline
model_name = 'distilbert-base-cased-distilled-squad'
model = pipeline(model=model_name, tokenizer=model_name,
task='question-answering')
from fastapi import FastAPI
app = FastAPI()
@app.post("/question_answering")
async def qa(input_data: QADataModel):
result = model(question = input_data.question, context=input_data.context)
return {"result": result["answer"]}
if __name__ == '__main__':
uvicorn.run('main:app', workers=1)
$ python main.py
结果,您将在终端中看到以下输出:
图 10.1 – fastAPI 在行动
$ curl --location --request POST 'http://127.0.0.1:8000/question_answering' \
--header 'Content-Type: application/json' \
--data-raw '{
"question":"What is extractive question answering?",
"context":"Extractive Question Answering is the task of extracting an answer from a text given a question. An example of a question answering dataset is the SQuAD dataset, which is entirely based on that task. If you would like to fine-tune a model on a SQuAD task, you may leverage the `run_squad.py`."
}'
结果,您将获得以下输出:
{"answer":"the task of extracting an answer from a text given a question"}
Curl 是一个有用的工具,但不如 Postman 方便。Postman 带有一个 GUI,与 CLI 工具 curl 相比,它更易于使用。使用Postman,从Download Postman | Get Started for Free安装它。
图 10.2 – Postman 的使用
您将在 Postman 的底部看到结果。
在下一节中,您将学习如何对基于 fastAPI 的 API 进行 docker 化。学习 Docker 基础知识对于使您的 API 可打包且更易于部署至关重要。
在生产过程中节省时间为了简化部署过程,使用 Docker 是必不可少的。隔离您的服务和应用程序非常重要。另外,请注意,无论底层操作系统如何,相同的代码都可以在任何地方运行。为了实现这一点,Docker 提供了强大的功能和封装。在使用它之前,您必须使用推荐的步骤安装它在 Docker 文档(Get Docker | Docker Documentation)中:
if __name__ == '__main__':
uvicorn.run('main:app', workers=1)
FROM python:3.7
RUN pip install torch
RUN pip install fastapi uvicorn transformers
EXPOSE 80
COPY ./app /app
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
$ docker build -t qaapi .
And easily start it:
$ docker run -p 8000:8000 qaapi
因此,您现在可以使用端口8000访问您的 API 。但是,您仍然可以使用 Postman,如上一节中所述,fastAPI Transformer 模型服务。
到目前为止,你已经学会了如何基于 Transformer 模型制作自己的 API 并使用 fastAPI 提供服务。然后,您学习了如何对其进行 docker 化。重要的是要知道关于 Docker,您必须了解许多选项和设置;我们在这里只介绍了 Docker 的基础知识。
在下一节中,您将学习如何使用 TFX 改进模型服务。
TFX 提供了一种更快更高效的方式服务于基于深度学习的模型。但它有一些你必须了解的重要关键点在你使用它之前。该模型必须是 TensorFlow 中保存的模型类型,以便 TFX Docker 或 CLI 可以使用它。让我们来看看:
from transformers import TFBertForSequenceClassification
model = TFBertForSequenceClassification.from_pretrained("nateraw/bert-base-uncased-imdb", from_pt=True)
model.save_pretrained("tfx_model", saved_model=True)
$ docker pull tensorflow/serving
$ docker run -d --name serving_base tensorflow/serving
$ docker cp tfx_model/saved_model tfx:/models/bert
$ docker commit --change "ENV MODEL_NAME bert" tfx my_bert_model
$ docker kill tfx
这将停止容器运行。
现在模型已经准备好并且可以由 TFX Docker 提供服务,您可以简单地将其与其他服务一起使用。我们需要另一个服务来调用 TFX 的原因是基于 Transformer模型具有标记器提供的特殊输入格式。
$ docker run -p 8501:8501 -p 8500:8500 --name bert my_bert_model
import uvicorn
from fastapi import FastAPI
from pydantic import BaseModel
from transformers import BertTokenizerFast, BertConfig
import requests
import json
import numpy as np
tokenizer =BertTokenizerFast.from_pretrained("nateraw/bert-base-uncased-imdb")
config = BertConfig.from_pretrained("nateraw/bert-base-uncased-imdb")
class DataModel(BaseModel):
text: str
app = FastAPI()
@app.post("/sentiment")
async def sentiment_analysis(input_data: DataModel):
print(input_data.text)
tokenized_sentence = [dict(tokenizer(input_data.text))]
data_send = {"instances": tokenized_sentence}
response = requests.post("http://localhost:8501/v1/models/bert:predict", data=json.dumps(data_send))
result = np.abs(json.loads(response.text)["predictions"][0])
return {"sentiment": config.id2label[np.argmax(result)]}
if __name__ == '__main__':
uvicorn.run('main:app', workers=1)
$ python main.py
现在,您的服务已启动并准备就绪使用。您可以使用 Postman 访问它,如以下屏幕截图所示:
图 10.3 – 基于 TFX 的服务的 Postman 输出
整体架构新服务的在 TFX Docker 中如下图所示:
图 10.4 – 基于 TFX 的服务架构
到目前为止,您已经学习了如何使用 TFX 为模型提供服务。但是,您需要学习如何使用 Locust 对服务进行负载测试。了解服务的限制以及何时使用量化或修剪来优化服务非常重要。在下一节中,我们将描述如何使用 Locust 在重负载下测试模型性能。
我们可以使用许多应用程序来加载测试服务。这些应用程序和库中的大多数都提供了有关服务响应时间和延迟的有用信息。他们也提供有关故障率的信息。Locust 是实现此目的的最佳工具之一。我们将使用它来负载测试为基于 Transformer 的模型提供服务的三种方法:仅使用 fastAPI、使用 dockerized fastAPI 和使用 fastAPI 的基于 TFX 的服务。让我们开始吧:
$ pip install locust
此命令将安装 Locust。下一步是让所有服务于相同任务的服务使用相同的模型。修复此测试中最重要的两个参数将确保所有服务的设计都相同,以服务于单一目的。使用相同的模型将帮助我们冻结其他任何东西并集中注意力关于方法的部署性能。
from locust import HttpUser, task
from random import choice
from string import ascii_uppercase
class User(HttpUser):
@task
def predict(self):
payload = {"text": ''.join(choice(ascii_uppercase) for i in range(20))}
self.client.post("/sentiment", json=payload)
通过使用HttpUser并创建继承自它的User类,我们可以定义一个HttpUser类。@task装饰器对于定义用户在生成后必须执行的任务至关重要。预测功能是用户在生成后将重复执行的实际任务。它将生成一个长度为20的随机字符串并将其发送到您的 API。
$ locust -f locust_file.py
Locust 将从设置开始您在locustfile中提供。您将在终端中看到以下内容:
图 10.5 – 开始 Locust 负载测试后的终端
可以看到,可以打开加载web界面所在的URL;即http://0.0.0.0:8089。
图 10.6 – Locust 网页界面
图 10.7 – Charts 选项卡中的 Locust 测试结果
结果如下表所示:
表 1 – 比较不同实施的结果
在上表中,每秒请求数( RPS ) 表示API 响应的每秒请求数,而平均响应时间( RT ) 表示服务响应给定调用所需的毫秒数。这些结果表明,基于 TFX 的 fastAPI是最快的。它具有更高的 RPS 和更低的平均 RT。所有这些测试均在配备 Intel(R) Core(TM) i7-9750H CPU、32 GB RAM 和禁用 GPU 的机器上进行。
在本节中,您学习了如何测试您的 API 并根据 RPS 和 RT 等重要参数衡量其性能。但是,现实世界的 API 可以执行许多其他压力测试,例如增加用户数量以使他们表现得像真实用户一样。要执行此类测试并以更真实的方式报告其结果,阅读 Locust 的文档并了解如何执行更高级的测试非常重要。
在本章中,您学习了使用 fastAPI 为 Transformer 模型提供服务的基础知识。您还学习了如何以更高级和更有效的方式为模型提供服务,例如使用 TFX。然后,您学习了负载测试和创建用户的基础知识。让这些用户成组或一个一个地产生,然后报告压力测试的结果,是本章的另一个主要主题。之后,您学习了 Docker 的基础知识以及如何以 Docker 容器的形式打包您的应用程序。最后,您学习了如何为基于 Transformer 的模型提供服务。