APIs 是在服务定义中定义的函数,它们作为 HTTP 或 gRPC 端点暴露出去。

如果一个函数用 @svc.api 装饰器装饰,它就是 APIs 的一部分。 APIs 可以定义为 Python 中的同步函数或异步协程。 APIs 通过调用服务定义中创建的函数和模型运行器(runners)中的预处理和后处理逻辑来满足请求。

同步 API 与异步 API 的对比

APIs 可以定义为 Python 中的同步函数或异步协程。 在之前的入门指南中创建的 API 是一个同步 API。

BentoML将智能地创建一个最佳规模的工作池(workers pool),以执行同步逻辑。

同步 APIs 很简单,能够为许多常见的模型服务场景完成工作。

# Create API function with pre- and post- processing logic
@svc.api(input=NumpyNdarray(), output=NumpyNdarray())
def predict(input_array: np.ndarray) -> np.ndarray:# Define pre-processing logicresult = await runner.run(input_array)# Define post-processing logicreturn result

当我们想要最大化服务的性能和吞吐量时,同步 API 就会出现不足。

如果处理逻辑受 IO 限制或同时调用多个运行器(runners),则首选异步 API。

以下异步 API 示例异步调用远程特征平台(feature store),同时调用两个运行器(runners),并返回更好的结果。

import aiohttp
import asyncio# Load two runners for two different versions of the ScikitLearn
# Iris Classifier models we saved before
runner1 = bentoml.sklearn.load_runner("iris_classifier_model:yftvuwkbbbi6zcphca6rzl235")
runner2 = bentoml.sklearn.load_runner("iris_classifier_model:edq3adsfhzi6zgr6vtpeqaare")# 使用调用特征平台的预处理逻辑创建异步 API 协程
@svc.api(input=NumpyNdarray(), output=NumpyNdarray())
async def predict(input_array: np.ndarray) -> np.ndarray:# 预处理:通过http调用一个远程特征平台接口async with aiohttp.ClientSession() as session:params = [("key", v) for v in a]async with session.get('https://features/get', params=input_array[0]) as resp:features = get_features(await resp.text())# 同时调用两个模型运行器并返回更好的结果results = await asyncio.gather(runner1.async_run(input_array, features),runner2.async_run(input_array, features),)return compare_results(results)

异步 API 实现更高效,因为当协程等待来自特征平台(feature store)或模型运行器(runners)的结果时,事件循环被释放以服务另一个请求。 BentoML 将根据可用的 CPU 内核数量智能地创建一个大小最佳的事件循环。 通常情况下,不需要进一步调整事件循环配置。

IO 描述符

输入和输出描述符定义 API 规范并在运行时验证 API 的参数和返回值。它们是通过 @svc.api 装饰器中的输入和输出参数指定的。

回想一下我们在入门指南中创建的 API。 这个预测 API 接受参数并以bentoml.io.NumpyNdarray 类型返回结果。NumpyNdarray 描述了类型为 numpy.ndarray 的返回值的参数,如 Python 函数签名中所指定。

import numpy as npfrom bentoml.io import NumpyNdarray# Create API function with pre- and post- processing logic
@svc.api(input=NumpyNdarray(), output=NumpyNdarray())
def predict(input_array: np.ndarray) -> np.ndarray:# Define pre-processing logicresult = await runner.run(input_array)# Define post-processing logicreturn result

IO 描述符有助于根据所选 IO 描述符的类型自动生成服务的 OpenAPI 规范。

我们可以通过提供 numpy.ndarray 对象的 dtype 来进一步自定义 IO 描述,具体如下所示。提供的 dtype 将在生成的 OpenAPI 规范中自动翻译。 IO 描述符将根据提供的 dtype 来验证参数和返回值。 验证失败的请求将导致错误。 我们还可以选择通过 validate 参数选择性地禁用验证。

import numpy as npfrom bentoml.io import NumpyNdarray# 创建一个带有预处理和后处理逻辑的API函数
@svc.api(input=NumpyNdarray(schema=np.dtype(int, 4), validate=True),output=NumpyNdarray(schema=np.dtype(int), validate=True),
)
def predict(input_array: np.ndarray) -> np.ndarray:# 定义预处理逻辑result = await runner.run(input_array)# 定义后处理逻辑return result

IO 描述符类型

内置类型

除了 NumpyNdarray,BentoML 还支持 bentoml.io 包下的各种其他内置 IO 描述符类型。 每种类型都支持类型验证和 OpenAPI 规范生成。

IO 描述符 数据类型 参数 Schema 类型
NumpyNdarray numpy.ndarray validate, schema numpy.dtype
PandasDataFrame pandas.DataFrame validate, schema pandas.DataFrame.dtypes
Json Python native types validate, schema Pydantic.BaseModel

复合类型

多个 IO 描述符可以在 API 装饰器的输入和输出参数中指定为元组。

复合 IO 描述符允许 API 接受多个参数并返回多个值。 每个 IO 描述符都可以使用独立的schema和验证逻辑进行自定义。

import typing as t
import numpy as np
from pydantic import BaseModelfrom bentoml.io import NumpyNdarray, Jsonclass FooModel(BaseModel):"""Foo model 文档"""field1: intfield2: floatfield3: strmy_np_input = NumpyNdarray.from_sample(np.ndarray(...))# 创建一个带有预处理和后处理逻辑的API函数
@svc.api(
input=Multipart(arr=NumpyNdarray(schema=np.dtype(int, 4), validate=True),json=Json(pydantic_model=FooModel),
)
output=NumpyNdarray(schema=np.dtype(int), validate=True),
)
def predict(arr: np.ndarray, json: t.Dict[str, t.Any]) -> np.ndarray:...

BentoML核心概念(二):API 和 IO 描述符相关推荐

  1. BentoML核心概念(一):服务定义

    服务定义是面向服务架构(SOA)的体现,是 BentoML 中的核心构建块,用户在其中定义服务运行时架构和模型服务的逻辑. 本文将剖析和解释服务定义中的关键组件.让您将全面了解服务定义的组成以及每个关 ...

  2. 很无聊但是又很重要的 计算机网络基础知识 --- “HTTP 核心概念(二) ” 【面试必问】

    目录 HTTP 标头 通用标头 Cache-Control Connection 持久性连接 Date Pragma Trailer Transfer-Encoding Upgrade Via War ...

  3. k8s-核心概念与API原语

    一.第一章(快速入门) 1.1.贵圈发展史 2004-2007 Google大规模使用容器Cgroups技术 2008.1 cgroups合并进入linux内核主干 2013.1 docker项目发布 ...

  4. python内置函数面向对象_Pyhton——面向对象进阶二:类的内置函数补充、描述符...

    Pyhton--面向对象进阶二: 一.类的内置函数补充 1.isinstance(obj,cls)--检查obj是否是该类的对象 class Hoo: def __init__(self,name,t ...

  5. 到底什么是文件描述符???

    文件描述符 1.文件描述符的引入 1.1 系统调用接口的引入 1.2 文件描述符 2.文件描述符 2.1 演示文件描述符 2.2 文件描述符的返回值 2.3 文件描述符底层原理(重点) 2.3 文件描 ...

  6. npm安装模块版本符_Java SE 9:模块和模块描述符基础知识(第2部分)

    npm安装模块版本符 I have already discuss about "Java 9 Module System" in high level in my previou ...

  7. linux文件描述符、软硬连接、输入输出重定向

    引用链接:https://blog.csdn.net/qq769651718/article/details/79459346 文件描述符的作用: 文件描述符是linux操作系统中特有的概念.其相当于 ...

  8. javascript描述符descriptor详解

    一.描述符对象是个什么东西? javascript里,有时候不想让用户修改某个对象的属性,则可以把这个对象的属性设置为不可写的,这样用户就不能对该属性进行修改了. 实际操作为: 这样看来,用户修改属性 ...

  9. socket 文件描述符

    Linux中,socket 也是被认为是文件的一种 window中,需要区分socket和文件 文件描述符:window中叫文件句柄:可以理解成分配的ID socket经过创建的过程中才会被分配文件描 ...

最新文章

  1. 《iOS 8应用开发入门经典(第6版)》——第1章,第1.6节小结
  2. vertical-align 和 img属性 和 鼠标样式
  3. 每日一皮:周六了,想跟你说一句...
  4. 字节跳动学习笔记:javaweb商城项目
  5. Linux-diff和diff3命令
  6. 用户接口(User exit)
  7. 右键菜单无响应_给电脑添加右键菜单重启资源管理器,让电脑不再死机!
  8. grep与sed批量处理多个文件中的字符串的方法
  9. Java泛型详解,通俗易懂只需5分钟
  10. .Net Core应用框架Util介绍(五)
  11. linux-权限管理acl高级
  12. Html中的map标签
  13. Android 系统(83)---屏幕尺寸
  14. Web Service初探
  15. 通俗地讲一下Web是什么意思。
  16. html线条倾斜代码,HTML5 居中斜向分割线切换的单页网页模板
  17. javafx 教程_Java验证(javafx)
  18. Python+Matplotlib绘制饼状图模拟南丁格尔玫瑰图
  19. 图像处理学习笔记2.0
  20. 制作EDM 邮件规范

热门文章

  1. 英语听力,口语常见的三个简读/略读/变读
  2. 如何区分项目负责人和项目管理者
  3. 这帮死磕技术的理工男造了一支笔
  4. 学会使用QT的帮助文档
  5. 零基础入门,花生壳骨灰级微信小程序开发教程
  6. veket linux安装到硬盘,安装veket到移动硬盘NTFS分区
  7. python 推箱子实验开发报告,python实现推箱子游戏
  8. PHP开源 | ysKit(ys工具包) - 微型Web框架
  9. Python测试框架pytest(23)插件 - pytest-picked、pytest-lazy-fixture
  10. 【定位不准的烦心事系列】第1篇:谈谈卫星定位的位置干扰