前言
官方文档:mlrun官方文档
MLOps仍然需要DevOps提倡的CI/CD框架,这是一种经过验证的方法,可以频繁地进行高质量的代码更新。然而,机器学习通过数据和模型验证扩展了集成阶段,而交付则解决了机器学习部署的复杂性。总之,CI/CD将数据、模型和代码组件组合在一起,以发布和更新预测服务 什么是CI/CD?让你的项目变得更加敏捷!
什么是MLRun
使用MLRun,用户可以在本地机器或云上选择任何IDE。MLRun打破了数据、ML、软件和DevOps/MLOps团队之间的孤岛,实现了协作和快速持续改进。能够自动化管理CI/CD中的各个阶段任务,通常分为以下几个:
Ingest and process data(数据的提取和处理)
提供多种在线或者离线数据源,支持大规模批处理或实时数据处理、数据沿袭(data lineage)和版本控制(versioning)、结构化和非结构化数据等。
数据的要求
批收集和处理方法比如ETL、SQL查询和批处理分析对实时操作工作流无效;因此,机器学习团队经常构建使用流处理、NoSQL和容器化微服务的独立数据管道。如今80%的数据是非结构化的,因此构建可操作数据管道的一个重要部分是将非结构化的文本、音频和视觉数据转换为机器学习或深度学习友好的数据组织。
MLOps解决方案应该包含一个特性存储,它只为批处理和实时场景定义一次数据收集和转换,自动处理特性而无需人工参与。并且存储功能不仅仅局限传统分析,支持对非结构化数据和复杂布局的转换。
Develop and train models(模型的建立和训练)
MLRun允许您轻松构建ML工作流(pipelines),从各种来源或特征存储中获取数据并对其进行处理,以多个参数大规模训练模型,测试模型,跟踪每个实验,以及注册,版本和部署模型等。MLRun提供可扩展的内置或自定义模型服务,可以与任何框架集成,同时,我们也可以自己预训练模型。
使用MLOps, ML团队构建机器学习管道,自动收集和准备数据,选择最佳特征,使用不同的参数集或算法运行训练,评估模型,并运行各种模型和系统测试。所有的执行以及它们的数据、元数据、代码和结果都必须进行版本控制和记录,提供快速的结果可视化,以便将它们与过去的结果进行比较,并了解哪些数据用于生成每个模型。
并且ML pipelines可以被手动触发,当(1)代码、依赖包或者参数改变时;(2)输入数据或者特征逻辑改变时;(3)检测到概念漂移,或者模型需要用新数据重新训练时。
Concept drift(概念漂移):是指在数据分布或者模型输入中的某种变化,导致模型性能下降,这种变化可能是渐变的,可能是突变的。
Deploy models and applications(模型部署和应用)
MLRun使用弹性和弹性的无服务器功能快速部署和管理生产级实时或批处理应用程序管道。MLRun处理整个ML应用程序:拦截应用程序/用户请求,运行数据处理任务,使用一个或多个模型进行推理,驱动操作,并与应用程序逻辑集成。
使用MLRun的优点之一是简化了部署过程。部署不仅仅是模型部署。模型通常作为更大的系统的一部分运行,该系统需要在执行模型之前和之后进行数据处理,并作为业务应用程序的一部分。 一般有两种模型部署方式:
实时部署
(1)实时部署:能够快速响应实时事件,MLRun 提供了专门的服务图(serving graph)来简化创建数据转换管道,从而确保在实时事件中的数据处理与批处理训练一致。 MLRun包含一些内置类,常用。 通常可以分为两个部分,首先是创建一个model
bash
import os
import urllib.request
import mlrun
model_path = os.path.abspath('sklearn.pkl')
# Download the model file locally 下载模型文件到本地
urllib.request.urlretrieve(mlrun.get_sample_path('models/serving/sklearn.pkl'), model_path)
# Set the base project name 设置项目名称
project_name_base = 'serving-test'
# Initialize the MLRun project object 初始化MLRun项目类
project = mlrun.get_or_create_project(project_name_base, context="./", user_project=True)
serving_function_image = "mlrun/mlrun"
serving_model_class_name = "mlrun.frameworks.sklearn.SklearnModelServer"
# Create a serving function 创建一个函数
serving_fn = mlrun.new_function("serving", project=project.name, kind="serving", image=serving_function_image)
# Add a model, the model key can be anything we choose. The class will be the built-in scikit-learn model server class
model_key = "scikit-learn"
serving_fn.add_model(key=model_key,
model_path=model_path,
class_name=serving_model_class_name)
当模型创建之后可以进行测试:
bash
# Test data to send
my_data = {"inputs":[[5.1, 3.5, 1.4, 0.2],[7.7, 3.8, 6.7, 2.2]]}
# Create a mock server in order to test the model
mock_server = serving_fn.to_mock_server()
# Test the serving function
mock_server.test(f"/v2/models/{model_key}/infer", body=my_data)
部署
bash
serving_fn.with_code(body=" ") # Workaround, required only for mlrun <= 1.0.2
# Deploy the serving function
serving_fn.apply(mlrun.auto_mount()).deploy()
# Check the result using the deployed serving function
serving_fn.invoke(path=f'/v2/models/{model_key}/infer',body=my_data)
(2)批处理推理:在大型数据集上运行的一个过程。通常,数据是从离线源(例如文件或数据库)读取的,结果也被写入离线目标。
创建个人服务类
模型服务/模型部署类实现了完整的模型服务功能,包括加载模型、预处理(后处理)、预测、可解释性和模型监控。 其中的类都继承于mlrun.serving.V2ModelServer,并且包含load() 函数能够加载模型文件,和predict()函数能够请求有效负载以及返回预测值。
有效负载(request payload)是指服务端在处理请求时,需要考虑客户端期望接收的数据格式,比如JSON 格式。
强制执行的两个方法
load() -- 下载文件并把文件存入内存,可以同步或者异步完成。
bash
from cloudpickle import load
import numpy as np
import mlrun
class ClassifierModel(mlrun.serving.V2ModelServer): #已经提前定义好的类
def load(self):#load函数 初始化各种参数
model_file, extra_data = self.get_model('.pkl')
self.model = load(open(model_file, 'rb'))
def predict(self, body: dict) -> list: #预测
feats = np.asarray(body['inputs'])
result: np.ndarray = self.model.predict(feats)
return result.tolist()
predict() -- 接受请求有效载荷,并返回预测/推理结果。
bash
import mlrun
from sklearn.datasets import load_iris
fn = mlrun.new_function('my_server', kind='serving')
# set the topology/router and add models
graph = fn.set_topology("router")
fn.add_model("model1", class_name="ClassifierModel", model_path="<path1>")
fn.add_model("model2", class_name="ClassifierModel", model_path="<path2>")
# create and use the graph simulator
server = fn.to_mock_server()
x = load_iris()['data'].tolist()
result = server.test("/v2/models/model1/infer", {"inputs": x})
注意:配置系统的拓扑结构或路由规则,并引入(添加)机器学习或其他类型的模型,以满足系统的需求或实现特定的功能。这可能涉及到网络配置、路由规则的设定,以及将模型集成到整个系统中。
其他可以重写的方法
preprocess() validate() postprocess() explain()
自定义api端口
添加一个method(方法) 然后调用或者触发
Test and deploy a model server(测试和部署一个模型服务器)
MLRun提供了一个模拟服务器作为服务运行时的一部分。这使您能够在本地环境中部署服务功能以进行测试。 然后测试数据:
bash
my_data = '''{"inputs":[[5.1, 3.5, 1.4, 0.2],[7.7, 3.8, 6.7, 2.2]]}'''
server.test("/v2/models/my_model/infer", body=my_data)
在部署阶段,使用code_to_function()调用创建服务函数
Monitor and alert(监控和报警🚨)
可观察性被内置到不同的MLRun对象(数据、函数、作业、模型、管道等)中,从而消除了复杂集成和代码插装的需要。使用MLRun,您可以观察应用程序/模型资源使用情况和模型行为(漂移、性能等),定义自定义应用程序指标,并触发警报或重新培训工作。 模型活动需要被跟踪到实时流和时间序列数据库中。监测数据用于创建实时仪表盘。
bash
fn.set_tracking(stream_path, batch, sample)
MLRun架构
主要采用Serverless Function技术:使用您喜欢的开发环境和简单的"本地"语义编写一次代码,然后按原样在不同的平台上大规模运行它。MLRun自动化了构建过程、执行、数据移动、扩展、版本控制、参数化、输出跟踪、CI/CD集成、部署到生产、监控等等。
无服务器架构
无服务器架构是一种云计算模型,其中开发者无需管理底层的服务器硬件或运行时环境,而是将代码封装为函数,按需运行。其中无服务器函数是一小段可执行的代码,通常执行特定的任务或服务。这些函数被触发时执行,而不是持续运行。无服务器函数的目标是按需、高效地处理请求,而不需要一直运行等待请求的到来。
Nuclio serverless function:使用Nuclio平台构建和部署的无服务器函数。
主要任务:数据准备、模型开发、模型和应用程序交付以及端到端监控是紧密相连的:它们不能在竖井中进行管理。这就是MLRun MLOps编排发挥作用的地方。 (未完,待补充 2023年12月6日)