Gradio App生产环境部署教程

如果机器学习模型没有投入生产供人们使用,就无法充分发挥其潜力。 根据我们的经验,将模型投入生产的最常见方法是为其创建 API。 然而,我们发现这个过程对于 ML 开发人员来说可能相当令人畏惧,特别是如果他们不熟悉 Web 开发的话。

在这篇文章中,我们将向你展示如何使用 FastAPI 和 Gradio 将模型公开为 API,然后创建一个 Docker 映像,该映像已准备好部署到容器实例中。

在线工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器

1、技术栈概述

我们使用 nq-distilbert-base-v1,这是一个在 Natural Questions 数据集上训练过的sentence-transformer模型。 该数据集包含来自 Google 搜索的真实问题以及来自维基百科的注释数据,提供了答案。 对于段落,我们将维基百科文章标题与各个文本段落一起编码。 我们使用的是简单英语维基百科,它仅包含 17 万篇文章,因此它要小得多,并且可以装入内存。

该模型还支持 GPU,因此可以在 Nvidia CUDA 设备上运行。

1.1 FastAPI

FastAPI 是一个现代、快速的 Web 框架,用于基于标准 Python 类型提示在 Python 中构建 API。 它开箱即用,支持通过 Swagger UI 使用 OpenAPI 标准自动生成 API 文档。

1.2 Gradio

Gradio 是一个 Python 库,用于为 ML 模型快速创建 Web 界面。 它构建在 Streamlit 之上,旨在易于使用和部署。 这对于向其他人展示你的模型并获得反馈非常有用且有趣。

1.3 Docker

Docker 是一个用于以容器形式构建、运行和运输应用程序的平台。 它是虚拟机的轻量级替代方案,是将应用程序及其依赖项打包到单个单元中的好方法。 可以说,它已经成为将应用程序投入生产的事实上的标准。

2、构建 API

我们将使用 FastAPI 来构建我们的 API,并使用 uvicorn 来运行它。 Gradio 将用于创建演示 Web 界面,并将其安装在 FastAPI 应用程序上。

理想情况下,你应该使用 python 3.7 及更高版本。 首先安装这些依赖项:

pip install fastapi uvicorn gradio sentence-transformers

在使用 FastAPI 之前,我们需要编写一个预测函数,该函数接受问题(模型的输入)并返回答案(模型的输出):

# main.py

from sentence_transformers import SentenceTransformer, util

bi_encoder = SentenceTransformer('nq-distilbert-base-v1')

### Create corpus embeddings containing the wikipedia passages
### To keep things summaraized, we are not going to show the code for this part

def predict(question):
    # Encode the query using the bi-encoder and find potentially relevant passages
    question_embedding = bi_encoder.encode(query, convert_to_tensor=True)
    hits = util.semantic_search(question_embedding, corpus_embeddings, top_k=top_k)
    hits = hits[0]  # Get the hits for the first query

    # transform hits into a list of dictionaries, and obtain passages with corpus_id
    results = [
        {
            "score": hit["score"],
            "title": passages[hit["corpus_id"]][0],
            "text": passages[hit["corpus_id"]][1],
        }
        for hit in hits
    ]

    return results

在 Github 上查看此文件的完整代码。

3、使用 Gradio 测试预测函数

为了快速测试预测功能,我们可以使用 Gradio 为其创建一个 Web 界面。 但首先,创建一个函数,从 Gradio 读取输入,调用预测函数,并以 Gradio 可以理解的格式返回输出。

# main.py

import gradio as gr

def gradio_predict(question: str):
    results = predict(question) # results is a list of dictionaries

    best_result = results[0]

    # return a tuple of the title and text as a string, and the score as a number
    return f"{best_result['title']}\n\n{best_result['text']}", best_result["score"]

我们现在可以为 gradio_predict 函数创建一个 Gradio 接口:

# main.py

demo = gr.Interface(
    fn=gradio_predict,
    inputs=gr.Textbox(
        label="Ask a question", placeholder="What is the capital of France?"
    ),
    outputs=[gr.Textbox(label="Answer"), gr.Number(label="Score")],
    allow_flagging="never",
)

demo.launch()

现在运行 python main.py 来启动 Gradio 演示,它现在可以在 localhost:7860 上使用。 由于下载和加载模型,因此初始化可能需要一段时间:

尝试发送问题,你应该会看到答案和分数。

4、创建 FastAPI 应用

现在,我们使用 FastAPI 在 /predict 创建一个 POST 请求端点,该端点接收带有问题键的 JSON 对象,并返回预测函数的结果。

# main.py

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Request(BaseModel):
    question: str


class Result(BaseModel):
    score: float
    title: str
    text: str


class Response(BaseModel):
    results: typing.List[Result] # list of Result objects


@app.post("/predict", response_model=Response)
async def predict_api(request: Request):
    results = predict(request.question)
    return Response(
        results=[
            Result(score=r["score"], title=r["title"], text=r["text"])
            for r in results
        ]
    )

让我们来分解一下。

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

这将创建一个 FastAPI 应用程序,我们现在可以向其添加端点。

class Request(BaseModel):
    question: str


class Result(BaseModel):
    score: float
    title: str
    text: str


class Response(BaseModel):
    results: typing.List[Result] # list of Result objects

这些是我们用来定义 API 预期输入和输出的 pydantic 模型。 定义这些模型是可选的,但这样做是一个很好的做法,因为它允许 FastAPI 自动生成 API 文档。

@app.post("/predict", response_model=Response)
async def predict_api(request: Request):
    results = predict(request.question)
    return Response(
        results=[
            Result(score=r["score"], title=r["title"], text=r["text"])
            for r in results
        ]
    )

这是我们添加到 FastAPI 应用程序的 POST 请求端点。 它接受一个请求模型,并返回一个我们之前定义的响应模型。 本质上,它运行我们编写的预测函数,并返回结果。

5、测试 FastAPI 应用程序

现在,我们可以通过运行 uvicorn main:app --reload 来测试 FastAPI 应用程序,然后使用包含问题键的 JSON 正文向 localhost:8000/predict 发送 POST 请求:

curl -X POST "http://localhost:8000/predict" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-d "{\"question\":\"What is the capital of France?\"}"

应该收到一个结果列表作为问题的答案:

{
  "results": [
    {
      "score": 0.8317935466766357,
      "title": "Capital of France",
      "text": "The capital of France is Paris. In the course of history, the national capital has been in many locations other than Paris."
    },
    {
      "score": 0.7517948150634766,
      "title": "Versailles, Yvelines",
      "text": "Versailles is a French city. It is in the western suburbs of Paris, 17.1 km. (10.6 miles) from the center of Paris. It is the \"capital\" of the Yvelines département. This city is very important for the History of France because it was formerly the capital of the kingdom of France."
    },
    {
      "score": 0.7379363775253296,
      "title": "Arrondissement of Sarlat-la-Canéda",
      "text": "The arrondissement of Sarlat-la-Canéda is an arrondissement of France. It is part of the Dordogne \"département\" in the Nouvelle-Aquitaine region. Its capital is the city of Sarlat-la-Canéda."
    },
    {
      "score": 0.7338694334030151,
      "title": "Arrondissement of Figeac",
      "text": "The arrondissement of Figeac is an arrondissement of France. It is part of the Lot \"département\" in the Occitanie region. Its capital is the city of Figeac."
    },
    {
      "score": 0.7309824228286743,
      "title": "Arrondissement of Confolens",
      "text": "The arrondissement of Confolens is an arrondissement of France, in the Charente department, Nouvelle-Aquitaine region. Its capital is the city of Confolens."
    }
  ]
}

6、浏览 FastAPI 文档

现在在浏览器中打开 localhost:8000/docs,你应该会看到 FastAPI 文档。

这对于其他开发人员了解如何使用你的 API 非常有用。

7、将 Gradio 演示安装为应用程序

要使用 FastAPI 应用程序和我们创建的 Gradio 演示构建统一的服务器,我们只需将 Gradio 演示安装到 FastAPI 应用程序中即可:

# main.py

# mounting at the root path
app = gr.mount_gradio_app(app, demo, path="/")

就这样,我们可以使用 uvicorn main:app --reload 重新启动应用程序,Gradio 演示现在应该可以在 localhost:8000 上使用。

8、构建 Docker 镜像

现在我们有了一个可以运行的应用程序,我们可以为其构建一个 Docker 镜像。

我们将使用 Docker Hub 上提供的 pytorch 基础镜像。 具体来说,我们将使用 pytorch/pytorch:1.13.1-cuda11.6-cudnn8-runtime 镜像,它是 PyTorch 1.13.1 启用 CUDA 的映像。

在构建图像之前,我们需要一个 Entrypoint.sh 脚本来使用 uvicorn 运行应用程序。 它还需要一个 PORT 环境变量,以便我们可以指定运行应用程序的端口:

# entrypoint.sh

#!/bin/bash

uvicorn --host 0.0.0.0 --port $PORT app:app

之后,我们在 Dockerfile 中编写一组用于构建映像的指令:

# Dockerfile

# Base image
FROM pytorch/pytorch:1.13.1-cuda11.6-cudnn8-runtime

# Set environment variables
ENV PORT=8000

# Install python dependencies
RUN pip install sentence-transformers fastapi uvicorn gradio

# Set working directory
WORKDIR /model

# Copy files to /model
COPY . .

# Make entrypoint.sh executable
RUN chmod +x ./entrypoint.sh

# Run entrypoint.sh when container starts
ENTRYPOINT [ "/model/entrypoint.sh" ]

为了构建镜像,我们运行:

docker build -t wiki-qa .

现在我们完成了! 我们可以运行镜像:

docker run -it --rm -p 8000:8000 wiki-qa

该应用程序应该再次在 localhost:8000 上可用。

该映像现在已准备好部署到任何容器服务。 它可以在 CPU 或 GPU 上运行,具体取决于你希望预测的速度。 例如,你可以使用 Deploifai 部署此映像,并在几分钟内获得生产就绪的 API 端点:

10、生产环境性能

我们在 Deploifai 上创建了 2 个测试部署,一个在 CPU 上,一个在 GPU (K80) 上,以比较模型在 CPU 与 GPU 上的性能:

部署vCPURAMAPI响应时间
CPU28 GB2 - 4 秒
GPU (K80)28 GB0.5 - 1 秒

原文链接:Gradio App生产部署 - BimAnt

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/134715.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

任正非说:到现在我们终于可以说没有失败,但我们还不能说成功。

你好!这是华研荟【任正非说】系列的第36篇文章,让我们聆听任正非先生的真知灼见,学习华为的管理思想和管理理念。 华研荟导语:今天的任正非先生讲话主要节选了他在2001-2004年的几个关于IPD、ISC的论述,可能大家会发现…

【C++】:内存管理:C++内存分布 || C++中动态内存管理(new || delete)

📭1. C/C内存分布 【说明】 🃏1. 栈又叫堆栈–非静态局部变量/函数参数/返回值等等,栈是向下增长的 🃏2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存&#xff…

跨域:利用CORS实现跨域访问

跨域知识点:跨域知识点 iframe实现跨域的四种方式:iframe实现跨域 JSONP和WebSocket实现跨域:jsonp和websocket实现跨域 目录 cors介绍 简介 两种请求 简单请求 基本流程 withCredentials 属性 非简单请求 预检请求 预检请求的回应 …

利用OGG实现PostgreSQL实时同步

📢📢📢📣📣📣 哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】!😜&am…

postman接口测试—Restful接口开发与测试

开发完接口,接下来我们需要对我们开发的接口进行测试。接口测试的方法比较多,使用接口工具或者Python来测试都可以,工具方面比如之前我们学习过的Postman或者Jmeter ,Python脚本测试可以使用Requests unittest来测试。 测试思路…

GPT 写作与改编

GPT 写作与改编 文商科GPT 写作收益 改编技巧【改编一段话】【改编评价】【意识预设】落差,让顾客看到就感性和冲动害怕,让顾客看到就想买和拥有画面,切换空间,瞬间代入,勾人魂魄对比,设置参考物&#xff0…

RT-DETR推理详解及部署实现

目录 前言1. RT-DETR-官方2. RT-DETR-U版2.1 RT-DETR预测2.2 RT-DETR预处理2.3 RT-DETR后处理2.4 RT-DETR推理 3. RT-DETR-C3.1 ONNX导出3.2 RT-DETR预处理3.3 RT-DETR后处理3.4 RT-DETR推理 4. RT-DETR部署4.1 源码下载4.2 环境配置4.2.1 配置CMakeLists.txt4.2.2 配置Makefil…

有奖 | Python 开发者 2023 年度调查

你好,我是 EarlGrey,一名双语学习者,会一点编程,目前已翻译出版《Python 无师自通》、《Python 并行编程手册》等书籍。 点击上方蓝字关注我,持续接收优质好书、高效工具和赚钱机会,一起提升认知和思维。 1…

免费分享一套基于Springboot+Vue的在线考试系统,挺漂亮的

大家好,我是java1234_小锋老师,看到一个不错的SpringbootVue的在线考试系统,分享下哈。 项目视频演示 【免费】springbootvue在线考试系统 Java毕业设计_哔哩哔哩_bilibili【免费】springbootvue在线考试系统 Java毕业设计项目来自互联网&a…

notes_质谱蛋白组学数据分析基础知识

目录 1. 蛋白组学方法学1.1 液相-质谱法1) 基本原理2) bottom-up策略的基本流程 1.2 PEA/Olink 2. 质谱数据分析2.1 原始数据格式2.2 分析过程1)鉴定2)定量3)预处理 2.3 下游分析 参考附录 1. 蛋白组学方法学 目前常见的蛋白组学方法学如下图…

Pinme POS无代码开发集成营销系统,实现广告推广自动化

无代码开发平台的优势 无代码开发平台如集简云是一款超级软件连接器,无需开发,无需代码知识就可以轻松打通千款软件之间的数据连接,构建自动化与智能化的业务流程。这种方式无需花费数周甚至数个月的时间做软件集成开发,最快20分…

【中国知名企业高管团队】系列65:方太FOTILE

今天华研荟为您介绍另一个行业的知名企业和高管团队信息——厨房电器这个细分领域,也产生了许多大的公司,而且这些头部公司都集中在一起,是当地重要的一个产业集群。 首先介绍细分领域的、号称做高端的方太厨电FOTILE。 一、关于方太集团FO…

JavaWeb Day08 Mybatis-入门

目录 ​编辑​编辑​编辑 一、快速入门程序 ①准备工作 ②引入Mybatis相关依赖,配置Mybatis ③编写SQL(注解/XML) ④单元测试 ⑤相关代码 1.pom.xml 2. application.properties 3.User.java 4. UserMapper.java 5.Test.java ⑥配置…

网络运维Day10

文章目录 SHELL基础查看有哪些解释器使用usermod修改用户解释器BASH基本特性 shell脚本的设计与运行编写问世脚本脚本格式规范执行shell脚本方法一方法二实验 变量自定义变量环境变量位置变量案例 预定义变量 变量的扩展运用多种引号的区别双引号的应用单引号的应用反撇号或$()…

【星海随笔】SDN neutron (三) Service-plugin

Neutron L3 L3的实现只负责路由的功能,传统路由器中的其他功能(如Firewalls、LB、VPN)都被独立出来实现了,因此ML3的实际需求比较少。 neutron-server 接到请求 –> 将请求发送到MQ –> neotron-plugins 得到请求 –> 发…

编程艺术之源:深入了解设计模式和设计原则

深入了解设计模式和设计原则 一、认识设计模式1.1、设计模式是什么?1.2、设计模式是怎么来的?1.3、设计模式解决了什么问题? 二、设计模式的基础2.1、面向对象思想2.2、设计原则 三、如何学习设计模式3.1、明确目的3.2、学习步骤 总结 一、认…

HTML跳转锚点

跳转锚点适用于本页面和其他页面的任意标签的跳转以及JavaScript的运行 使用方法即给标签加上独一无二的id属性&#xff0c;再使用a标签跳转 如果是其他页面的标签只需加上其他页面的路径&#xff0c;eg.href"其他页面的路径#zp1" id属性的最好不要使用数字开头 <…

Vert.x学习笔记-什么是Verticle

什么是Verticle Verticle是Vert.x应用中的基本编程单元&#xff0c;类似于Java中的Servlet、Pojo Bean或Akka中的Actor。它可以使用不同的编程语言实现&#xff0c;并且这些由不同编程语言实现的Verticle可以封装到一个模块中&#xff0c;进而部署到一个Vert.x应用中。Verticl…

关系型数据库Redis安装与写入数据

文章目录 安装和初步选择数据库创建键值对数据类型 安装和初步 安装 Redis是开源的跨平台非关系型数据库&#xff0c;特点是占用资源低、查询速度快。 首先&#xff0c;在Github上下载最新发布的Redis-xxxx.zip压缩文件&#xff0c;下载之后解压&#xff0c;并将解压后的路径…

要找事做,我真怕被闲死

要找事做&#xff0c;我真怕被闲死 | 昨晚睡足了5个多小时&#xff0c;元气开始恢复&#xff0c;今晨6点钟醒来&#xff0c;如厕后无睡意&#xff0c;便窝在被子里闭目养神&#xff0c;同时想心事。 7点钟翻身起床穿衣洗刷后&#xff0c;烧瓶开水泡杯浓茶&#xff0c;打开电脑…