精通 Transformers(四)(1)

简介: 精通 Transformers(四)

第十章:提供 Transformer 模型

到目前为止,我们已经探讨了围绕 Transformer 的许多方面,你已经学会了如何从头开始训练和使用 Transformer 模型。您还学会了如何为许多任务进行微调。然而,我们仍然不知道如何在生产中提供这些模型。与任何其他现实生活和现代解决方案一样,基于自然语言处理NLP)的解决方案必须能够在生产环境中提供服务。然而,在开发这种解决方案时必须考虑响应时间等指标。

本章将介绍如何在具有 CPU/GPU 的环境中提供基于 Transformer 的 NLP 解决方案。将在此处描述用于机器学习部署的TensorFlow ExtendedTFX)解决方案。还将说明用于作为 API 提供 Transformer 的其他解决方案,例如 FastAPI。您还将了解 Docker 的基础知识,以及如何将您的服务 docker 化并使其可部署。最后,您将学习如何使用 Locust 对基于 Transformer 的解决方案进行速度和负载测试。

在本章中,我们将涵盖以下主题:

  • 快速 API 变换器模型服务
  • Docker 化 APIs
  • 使用 TFX 进行更快的变换器模型服务
  • 使用 Locust 进行负载测试

技术要求

我们将使用 Jupyter Notebook、Python 和 Dockerfile 来运行我们的编码练习,这将需要 Python 3.6.0。需要安装以下软件包:

  • TensorFlow
  • PyTorch
  • Transformer >=4.00
  • 快速 API
  • Docker
  • Locust

现在,让我们开始吧!

本章中的所有编码练习笔记本将在以下 GitHub 链接中提供: github.com/PacktPublishing/Mastering-Transformers/tree/main/CH10

点击以下链接查看动态演示视频: bit.ly/375TOPO

快速 API 变换器模型服务

有许多我们可以用来提供服务的 web 框架。 Sanic、Flask 和 fastAPI 只是一些例子。然而,fastAPI 最近因其速度和可靠性而备受关注。在本节中,我们将使用 fastAPI 并根据其文档学习如何构建服务。我们还将使用pydantic来定义我们的数据类。让我们开始吧!

  1. 在开始之前,我们必须安装pydantic和 fastAPI:
$ pip install pydantic
$ pip install fastapi
  1. 下一步是使用pydantic为装饰 API 输入的数据模型进行建模。但是在形成数据模型之前,我们必须了解我们的模型是什么,并确定其输入。
    我们将使用问答QA)模型。正如你从第六章中所知,Fine-Tuning Language Models for Token Classification,输入是问题和上下文的形式。
  2. 通过使用以下数据模型,您可以创建 QA 数据模型:
from pydantic import BaseModel
class QADataModel(BaseModel):
     question: str
     context: str
  1. 我们必须只加载模型一次,而不是为每个请求加载它;相反,我们将预加载它一次并重复使用它。因为每次我们向服务器发送请求时,端点函数都会被调用,这将导致模型每次都被加载:
from transformers import pipeline
model_name = 'distilbert-base-cased-distilled-squad'
model = pipeline(model=model_name, tokenizer=model_name,   
                          task='question-answering')
  1. 下一步是为调节应用程序创建一个 fastAPI 实例:
from fastapi import FastAPI
app = FastAPI()
  1. 然后,您必须使用以下代码创建一个 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"]}
  1. 对于使该函数以异步模式运行,重要的是使用 async;这将使请求并行运行。您还可以使用 workers 参数来增加 API 的工作线程数,并使其同时回答不同和独立的 API 调用。
  2. 使用 uvicorn,您可以运行应用程序并将其作为 API 提供。Uvicorn 是用于 Python API 的高速服务器实现,使其尽可能快速运行。使用以下代码:
if __name__ == '__main__':
           uvicorn.run('main:app', workers=1)
  1. 请记住,上述代码必须保存在 .py 文件中(例如 main.py)。您可以使用以下命令运行它:
$ python main.py
  1. 结果如下,您将在终端中看到以下输出:

    图 10.1 – fastAPI 实战
  2. 下一步是使用并测试它。我们可以使用许多工具来做这件事,但 Postman 是其中之一。在学习如何使用 Postman 之前,请使用以下代码:
$ 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`."
}'
  1. 结果如下:
{"answer":"the task of extracting an answer from a text given a question"}
  1. Curl 是一个有用的工具,但不如 Postman 方便。Postman 带有图形用户界面,比起是一个 CLI 工具的 curl 更易于使用。要使用 Postman,请从www.postman.com/downloads/安装它。
  2. 安装完 Postman 后,您可以轻松使用它,如下截图所示:
    图 10.2 – Postman 使用
  3. 设置 Postman 以使用您的服务的每个步骤在上述截图中都有编号。让我们来看看它们:
  4. 选择 POST 作为您的方法。
  5. 输入完整的端点 URL。
  6. 选择 Body
  7. Body 设置为 raw
  8. 选择 JSON 数据类型。
  9. 以 JSON 格式输入您的输入数据。
  10. 单击 Send
    您将在 Postman 的底部部分看到结果。

在下一节中,您将学习如何将基于 fastAPI 的 API docker 化。学习 Docker 基础知识对于使您的 API 可打包并更容易部署至关重要。

Docker 化 API

为了在生产过程中节省时间并简化部署过程,使用 Docker 是至关重要的。对于隔离您的服务和应用程序非常重要。此外,请注意,相同的代码可以在任何地方运行,而不受底层操作系统的限制。为了实现这一点,Docker 提供了出色的功能和打包。在使用它之前,您必须按照 Docker 文档中推荐的步骤安装它(docs.docker.com/get-docker/):

  1. 首先,将 main.py 文件放置在 app 目录中。
  2. 接下来,您必须通过指定以下内容来删除代码的最后一部分:
if __name__ == '__main__':
     uvicorn.run('main:app', workers=1)
  1. 下一步是为您的 fastAPI 创建一个 Dockerfile;您之前已经创建过了。为此,您必须创建一个包含以下内容的 Dockerfile:
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"]
  1. 然后,您可以构建您的 Docker 容器:
$ docker build -t qaapi .
And easily start it:
$ docker run -p 8000:8000 qaapi
  1. 因此,您现在可以使用8000端口访问您的 API。但是,您仍然可以使用 Postman,如前一节所述,fastAPI Transformer model serving

到目前为止,您已经学会了如何基于 Transformer 模型创建自己的 API,并使用 fastAPI 提供服务。然后学习了如何 dockerize 它。重要的是要知道,关于 Docker,您必须学习许多选项和设置;我们这里只覆盖了 Docker 的基础知识。

在下一节中,您将学习如何使用 TFX 来改进您的模型服务。

使用 TFX 进行更快的 Transformer 模型服务

TFX 提供了一种更快速和更高效的方式来提供基于深度学习的模型。但是在使用之前,您必须了解一些重要的关键点。模型必须是来自 TensorFlow 的保存模型类型,以便它可以被 TFX Docker 或 CLI 使用。让我们来看一看:

  1. 您可以通过使用来自 TensorFlow 的保存模型格式来执行 TFX 模型服务。有关 TensorFlow 保存模型的更多信息,请阅读官方文档:www.tensorflow.org/guide/saved_model。要从 Transformers 创建保存模型,您只需使用以下代码:
from transformers import TFBertForSequenceClassification
model = \ TFBertForSequenceClassification.from_pretrained("nateraw/bert-base-uncased-imdb", from_pt=True)
model.save_pretrained("tfx_model", saved_model=True)
  1. 在理解如何使用它来为 Transformers 提供服务之前,需要拉取 TFX 的 Docker 镜像:
$ docker pull tensorflow/serving
  1. 这将拉取正在提供的 TFX Docker 容器。下一步是运行 Docker 容器并将保存的模型复制到其中:
$ docker run -d --name serving_base tensorflow/serving
  1. 您可以使用以下代码将保存的文件复制到 Docker 容器中:
$ docker cp tfx_model/saved_model tfx:/models/bert
  1. 这将把保存的模型文件复制到容器中。但是,您必须提交更改:
$ docker commit --change "ENV MODEL_NAME bert" tfx my_bert_model
  1. 现在一切都准备就绪,您可以终止 Docker 容器:
$ docker kill tfx
  1. 这将停止容器的运行。
    现在模型已经准备好,并且可以通过 TFX Docker 提供服务,您可以简单地与另一个服务一起使用它。我们需要另一个服务来调用 TFX 的原因是,基于 Transformer 的模型有一个由 tokenizer 提供的特殊输入格式。
  2. 为此,您必须创建一个 fastAPI 服务,该服务将模拟由 TensorFlow 服务容器提供的 API。在编写代码之前,您应该通过给予它运行 BERT-based 模型的参数来启动 Docker 容器。这将帮助您修复任何错误:
$ docker run -p 8501:8501 -p 8500:8500 --name bert my_bert_model
  1. 下面的代码包含了main.py文件的内容:
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)
  1. 我们加载了config文件,因为标签存储在其中,我们需要它们以在结果中返回。您可以简单地使用python运行此文件:
$ python main.py
  1. 现在,您的服务已经启动并准备就绪。您可以使用 Postman 访问它,如下图所示:

图 10.3—基于 TFX 服务的 Postman 输出

TFX Docker 中新服务的整体架构如下图所示:

图 10.4—基于 TFX 服务的架构

到目前为止,您已经学会了如何使用 TFX 提供模型。然而,您还需要学会如何使用 Locust 进行负载测试。了解服务的限制以及何时通过量化或修剪进行优化是非常重要的。在下一节中,我们将描述如何使用 Locust 在高负载下测试模型性能。


精通 Transformers(四)(2)https://developer.aliyun.com/article/1510720

相关文章
|
8月前
|
机器学习/深度学习 自然语言处理 PyTorch
精通 Transformers(一)(2)
精通 Transformers(一)
200 4
|
8月前
|
编解码 自然语言处理 数据可视化
精通 Transformers(四)(4)
精通 Transformers(四)
190 0
|
8月前
|
机器学习/深度学习 数据可视化 API
精通 Transformers(四)(2)
精通 Transformers(四)
80 0
|
8月前
|
自然语言处理 数据可视化 NoSQL
精通 Transformers(四)(3)
精通 Transformers(四)
96 0
|
6月前
|
自然语言处理 PyTorch TensorFlow
Transformers 4.37 中文文档(二)(4)
Transformers 4.37 中文文档(二)
47 2
|
6月前
|
存储 PyTorch 测试技术
Transformers 4.37 中文文档(八十三)(4)
Transformers 4.37 中文文档(八十三)
36 2
|
6月前
|
存储 自然语言处理 测试技术
Transformers 4.37 中文文档(八)(1)
Transformers 4.37 中文文档(八)
38 2
|
6月前
|
存储 编解码 PyTorch
Transformers 4.37 中文文档(八十三)(3)
Transformers 4.37 中文文档(八十三)
32 2
|
6月前
|
自然语言处理 并行计算 数据可视化
Transformers 4.37 中文文档(六)(2)
Transformers 4.37 中文文档(六)
35 0
|
8月前
|
自然语言处理 算法 算法框架/工具
精通 Transformers(一)(4)
精通 Transformers(一)
134 4

热门文章

最新文章