基于OAM和kfserving实现通用化云原生模型应用部署
kfserving 是 kubeflow 一个用于构建部署标准化的算法模型 serverless 组件,但其和 knative 深度绑定,对传输链路进行了隐藏,如封装istio,这样复杂的结构不利于生产环境直接使用,这里通过 kubevela 实现的 OAM 将 serverless 流程重新进行简单的标准化封装,以实现一个简单的算法模型 serverless。
背景
如何为算法团队提供高效的工程化上云支持是云原生时代一个很重要的也很有意义的课题,现在开源社区比较完善的应该是 Kubeflow —— 一系列 ML 实验部署环境工具的集合,不过整体来看比较笨重,不适合小团队生产环境快速落地,这里基于 kubevela 和 kfserving 实现一个算法标准化模型的例子,供参考。
项目介绍
项目地址:https://github.com/shikanon/vela-example/tree/main/example/sklearnserver
通过 kubevela 提供了三种对象 mpserver, hpa, httproute。
- mpserver 主要负责生成 deployment 和 service 资源,是程序运行的主体
- httroute 主要负责生成对外暴露的端口,访问 url
- hpa 主要保证服务的可扩展性
部署前准备工作
由于使用到vela
,所以需要先下载vela
客户端
创建一个 sklearn 的服务
案例放在 exmaple/sklearnserver
下面。
- 本地镜像编译并运行:
# 编译 docker build -t swr.cn-north-4.myhuaweicloud.com/hw-zt-k8s-images/sklearnserver:demo-iris -f sklearn.Dockerfile .
- 上传到华为云镜像仓库
docker login swr.cn-north-4.myhuaweicloud.com docker push swr.cn-north-4.myhuaweicloud.com/hw-zt-k8s-images/sklearnserver:demo-iris
- 创建一个
demo-iris-01.yaml
的应用文件
name: demo-iris-01 services: demo-iris: type: mpserver image: swr.cn-north-4.myhuaweicloud.com/hw-zt-k8s-images/sklearnserver:demo-iris ports: [8080] cpu: "200m" memory: "250Mi" httproute: gateways: ["external-gateway"] hosts: ["demo-iris.rcmd.testing.mpengine"] servernamespace: rcmd serverport: 8080 hpa: min: 1 max: 1 cpuPercent: 60
因为这里使用的是rcmd
命名空间,在创建的时候需要切换,可以通过vela dashboard 通过可视化界面创建一个 rcmd
命名空间的环境:
vela dashboard
成功后可以通过vela env
查看:
$ vela env ls NAME CURRENT NAMESPACE EMAIL DOMAIN default default rcmd * rcmd
- 在云原生环境运行应用
$ vela up -f demo-iris-01.yaml Parsing vela appfile ... Load Template ... Rendering configs for service (demo-iris)... Writing deploy config to (.vela/deploy.yaml) Applying application ... Checking if app has been deployed... App has not been deployed, creating a new deployment... ✅ App has been deployed 🚀🚀🚀 Port forward: vela port-forward demo-iris-01 SSH: vela exec demo-iris-01 Logging: vela logs demo-iris-01 App status: vela status demo-iris-01 Service status: vela status demo-iris-01 --svc demo-iris
测试
部署好后可以测试:
$ curl -i -d '{"instances":[[5.1, 3.5, 1.4, 0.2]]}' -H "Content-Type: application/json" -X POST demo-iris.rcmd.testing.mpengine:8000/v1/models/model:predict {"predictions": [0]}
实现说明
kfserver 开发算法 server
kfserver 提供了多种常用框架的 server,比如 sklearn, lgb, xgb, pytorch 等多种服务的 server 框架, kfserver 基于 tornado 框架进行开发,其提供了 模型加载,接口健康检测,预测及 参考解释等多个抽象接口,详细见kfserving/kfserving/kfserver.py
:
... def create_application(self): return tornado.web.Application([ # Server Liveness API returns 200 if server is alive. (r"/", LivenessHandler), (r"/v2/health/live", LivenessHandler), (r"/v1/models", ListHandler, dict(models=self.registered_models)), (r"/v2/models", ListHandler, dict(models=self.registered_models)), # Model Health API returns 200 if model is ready to serve. (r"/v1/models/([a-zA-Z0-9_-]+)", HealthHandler, dict(models=self.registered_models)), (r"/v2/models/([a-zA-Z0-9_-]+)/status", HealthHandler, dict(models=self.registered_models)), (r"/v1/models/([a-zA-Z0-9_-]+):predict", PredictHandler, dict(models=self.registered_models)), (r"/v2/models/([a-zA-Z0-9_-]+)/infer", PredictHandler, dict(models=self.registered_models)), (r"/v1/models/([a-zA-Z0-9_-]+):explain", ExplainHandler, dict(models=self.registered_models)), (r"/v2/models/([a-zA-Z0-9_-]+)/explain", ExplainHandler, dict(models=self.registered_models)), (r"/v2/repository/models/([a-zA-Z0-9_-]+)/load", LoadHandler, dict(models=self.registered_models)), (r"/v2/repository/models/([a-zA-Z0-9_-]+)/unload", UnloadHandler, dict(models=self.registered_models)), ]) ...
这里我们使用的 sklearn server 的案例主要实现了 predict
接口:
import kfserving import joblib import numpy as np import os from typing import Dict MODEL_BASENAME = "model" MODEL_EXTENSIONS = [".joblib", ".pkl", ".pickle"] class SKLearnModel(kfserving.KFModel): # pylint:disable=c-extension-no-member def __init__(self, name: str, model_dir: str): super().__init__(name) self.name = name self.model_dir = model_dir self.ready = False def load(self) -> bool: model_path = kfserving.Storage.download(self.model_dir) paths = [os.path.join(model_path, MODEL_BASENAME + model_extension) for model_extension in MODEL_EXTENSIONS] for path in paths: if os.path.exists(path): self._model = joblib.load(path) self.ready = True break return self.ready def predict(self, request: Dict) -> Dict: instances = request["instances"] try: inputs = np.array(instances) except Exception as e: raise Exception( "Failed to initialize NumPy array from inputs: %s, %s" % (e, instances)) try: result = self._model.predict(inputs).tolist() return {"predictions": result} except Exception as e: raise Exception("Failed to predict %s" % e)

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
一文让你了解如何快速、优雅的实现导出Excel
前言: 春节假期刚刚过去,大家是不是已经开始了搬砖生活啦,嘻嘻 o(∩_∩)o ,可我还在休假中呢 ! 好啦,咱们言归正传,开始聊聊正文。做过后端管理系统的同学,大概率都会收到过实现 导出Excel 的功能需求,因为这个功能在后台管理系统中是个必备功能。 那大家是怎么实现这个功能的呢? 使用Apache提供POI组件实现; 使用现成的、简便的第三方工具库(避免重复造轮子) Hutool 工具库中的Excel工具类 EasyExcel 阿里开源的基于Java的简单、省内存的读写Excel工具库 接下来咱们来聊聊使用 Hutool、EasyExcel 工具库实现导出Excel。 使用第三方库实现导出Excel 业界有句话:不重复造轮子。 使用工具类可以减少日常繁琐的编码,减少重复的编码时间,提高开发效率。 作为程序员,应该多善于利用工具减少代码冗余,美化自己的代码。 使用 Hutool 工具库实现导出Excel: 1、首先添加依赖 在pom.xml中添加上依赖: <!--hutool 导出 Excel 工具组件--> <dependency> <groupId...
- 下一篇
通过gitee管理hexo管理发布内容
想法 最原始的办法是通过ftp或者winscp这样的工具能实现内容上传,但是不够简化,首先你要登录服务器,然后找到相应文件夹进行更新。 第二种方法是先更新gitee仓库,然后通过ssh登录服务器,然后从仓库pull下所有代码 第三种方法是不需要gitee仓库,直接在服务器建一个空仓库,然后把本地发布文件push到服务器仓库上 上面3种方法,第1种最原始,第2种比较繁琐,第3种简单可操作,但是第3种有一个问题,就是代码管理全部在服务器上,可视性比较差,能不能通过gitee管理代码,包括原始文件,然后一旦用户push,通过钩子函数,触发服务器主动拉取,这样,所有操作都简化为了本地的一个git push指令。说干就干,问了一圈度娘,果然高手在民间,几个关键步骤都有相应的帖子介绍。 第一步 建立hexo空仓库 本地把项目文件统统push上去,除了node_module文件夹。这样,项目文件也不会丢失,便于以后复用。 第二步 建立服务器到hexo仓库私钥通信 1. 创建ssh连接密钥 参看https://gitee.com/help/articles/4181#article-header0 ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Hadoop3单机部署,实现最简伪集群
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker安装Oracle12C,快速搭建Oracle学习环境