一、为什么要做模型部署流水线的自动化控制
做过AI项目的人都懂,模型训练完只是第一步,真正麻烦的是把模型推到线上给人用的过程。以前很多团队的做法是:开发先把模型文件拷到服务器,手动改配置文件,再重启服务,整个过程全靠人盯。一旦模型迭代快,比如每周要更一次,或者同时要管十几个模型,很容易出问题——比如拷错版本、配置漏改、忘了重启服务,最后线上出bug,排查起来花半天。
所以大家需要一套能自动跑的流程:只要新模型训练好,自动把它部署到线上,中间不用人插手,出错了还能自动回滚。这就是模型部署流水线的作用,而MLflow是现在做这个的常用工具,它能帮我们管理模型的版本、部署、监控,而且既有命令行(CLI)能直接敲,又有接口(REST API)能写程序调用,刚好适配自动化的需求。
二、MLflow的基础能力铺垫
在说具体操作之前,得先把MLflow最核心的两个功能说清楚,不然后面的操作会看不懂。
2.1 MLflow模型仓库的作用
MLflow有个专门存模型的地方叫“模型仓库”,你可以把它理解成AI模型的“云盘”,和普通云盘不一样的是,它存的不是随便的文件,而是打包好的模型包。这个包里面不仅有模型本身,还有模型的版本号、训练时间、用的是什么框架(比如TensorFlow、PyTorch)、依赖的Python版本这些信息,部署的时候能自动把这些信息用上,不用手动去配。
2.2 CLI和REST API的区别
MLflow给了两种操作方式:
第一种是CLI,就是在电脑的命令行窗口里敲命令,比如敲mlflow models serve就能启动一个模型服务,适合手动测试或者写简单的脚本。
第二种是REST API,就是用程序(比如Python、Java)发网络请求来操作MLflow,比如用Python发个请求就能把新模型推到仓库,适合写自动化的程序,能和其他系统(比如训练平台、监控系统)连起来。
三、完整的自动化部署流水线实现
这部分会给一个完整的例子,从新模型推到仓库,到自动部署,再到出错回滚,所有步骤都能自动跑。这里统一用Python作为示例的技术栈,所有代码都能直接复制运行。
3.1 第一步:准备MLflow环境
首先得先把MLflow的服务跑起来,因为模型仓库、部署服务都要靠它。你可以用下面的命令启动MLflow服务,这里把模型仓库存在本地的./mlflow-artifacts文件夹里,服务端口设为5000:
# 启动MLflow服务,指定模型存储路径和端口
mlflow server --backend-store-uri sqlite:///mlflow.db --default-artifact-root ./mlflow-artifacts --host 0.0.0.0 --port 5000
启动之后,你可以在浏览器打开http://localhost:5000,就能看到MLflow的管理界面了,比如能看到所有模型的版本、部署的服务状态。
3.2 第二步:把新模型推到模型仓库
假设你已经训练好了一个简单的房价预测模型,现在要把它推到MLflow的模型仓库。这里用Python写代码,先把模型打包好再上传:
# 技术栈:Python 3.9 + scikit-learn 1.3.0 + mlflow 2.7.1
import mlflow
import mlflow.sklearn
from sklearn.linear_model import LinearRegression
import numpy as np
# 1. 训练一个简单的房价预测模型(模拟训练好的模型)
# 输入:房屋面积、房间数;输出:房价
X = np.array([[100, 2], [150, 3], [200, 4], [250, 5]])
y = np.array([200, 300, 400, 500]) # 单位:万元
model = LinearRegression()
model.fit(X, y)
# 2. 配置MLflow的连接地址(因为我们启动的MLflow服务在本地5000端口)
mlflow.set_tracking_uri("http://localhost:5000")
# 3. 定义模型的名称(这个名称是唯一的,用来标识这个模型)
model_name = "house-price-prediction"
# 4. 把模型推到MLflow的模型仓库
with mlflow.start_run():
# 记录模型的参数(可选,方便后续查看模型信息)
mlflow.log_param("model_type", "LinearRegression")
# 把模型打包上传,指定模型名称
mlflow.sklearn.log_model(
sk_model=model,
artifact_path="model",
registered_model_name=model_name # 注册到模型仓库的名称
)
# 获取刚上传的模型版本号(后续部署需要用到)
client = mlflow.tracking.MlflowClient()
registered_model = client.get_registered_model(model_name)
latest_version = registered_model.latest_versions[0].version
print(f"新模型上传成功,版本号:{latest_version}")
运行这段代码后,新模型就会被推到MLflow的模型仓库,版本号会自动累加,比如第一次是v1,第二次是v2。
3.3 第三步:用CLI实现自动部署
现在模型已经在仓库里了,接下来要把它部署成一个可以调用的服务。这里用CLI写一个简单的脚本,只要把模型版本号传进去,就能自动部署:
# 技术栈:Bash(命令行脚本)
# 部署脚本:deploy_model.sh
# 接收两个参数:模型名称、模型版本号
MODEL_NAME=$1
MODEL_VERSION=$2
PORT=$3 # 服务端口,比如8000
# 检查参数是否完整
if [ $# -ne 3 ]; then
echo "用法:./deploy_model.sh 模型名称 模型版本号 端口"
echo "示例:./deploy_model.sh house-price-prediction 1 8000"
exit 1
fi
# 用MLflow CLI启动模型服务,这里指定模型的路径(MLflow的模型路径格式是:models:/模型名称/版本号)
mlflow models serve -m "models:/${MODEL_NAME}/${MODEL_VERSION}" -p ${PORT} --no-conda --workers 2
这个脚本的意思是,把仓库里指定版本的模型,启动成一个监听在指定端口的服务。启动之后,你可以用下面的命令测试服务是否正常:
# 测试模型服务,发送一个请求,输入房屋面积120、房间数2
curl -X POST -H "Content-Type: application/json" -d '{"inputs": [[120, 2]]}' http://localhost:8000/invocations
如果返回了预测的房价,说明部署成功了。
3.4 第四步:用REST API实现自动化控制
CLI适合写简单的脚本,但如果要把部署流程和其他系统连起来,比如模型训练完自动触发部署,或者监控到服务异常自动回滚,就得用REST API了。下面用Python写一个自动化控制程序,实现三个功能:检查模型服务状态、部署新模型、出错回滚到上一个版本。
# 技术栈:Python 3.9 + requests 2.31.0 + mlflow 2.7.1
import requests
import mlflow
from mlflow.tracking import MlflowClient
# 配置MLflow的连接地址
MLFLOW_URI = "http://localhost:5000"
mlflow.set_tracking_uri(MLFLOW_URI)
client = MlflowClient()
# 定义一个函数:检查模型服务是否正常
def check_service_status(service_url):
try:
# 发送一个测试请求,检查服务是否响应
test_data = {"inputs": [[120, 2]]}
response = requests.post(
f"{service_url}/invocations",
json=test_data,
timeout=5 # 5秒没响应就认为服务异常
)
return response.status_code == 200
except Exception as e:
print(f"服务异常:{str(e)}")
return False
# 定义一个函数:部署指定版本的模型
def deploy_model(model_name, model_version, service_port):
# 先停止旧的服务(如果有的话,这里用ps命令查找进程并杀死,实际生产环境可以用容器管理工具比如Docker、K8s)
import os
os.system(f"pkill -f 'mlflow models serve.*{service_port}'")
# 用REST API启动新的服务(这里其实是调用MLflow的CLI,但可以用程序来控制)
# 实际生产环境可以用Docker来启动服务,这里简化处理
os.system(f"nohup mlflow models serve -m models:/{model_name}/{model_version} -p {service_port} --no-conda --workers 2 > /dev/null 2>&1 &")
# 等待服务启动
import time
time.sleep(10)
# 检查服务状态
service_url = f"http://localhost:{service_port}"
if check_service_status(service_url):
print(f"模型v{model_version}部署成功,服务地址:{service_url}")
return True
else:
print(f"模型v{model_version}部署失败")
return False
# 定义一个函数:回滚到上一个版本
def rollback(model_name, service_port):
# 获取当前部署的版本(假设我们把当前版本存在一个文件里,实际可以存在数据库)
try:
with open("current_version.txt", "r") as f:
current_version = int(f.read().strip())
except FileNotFoundError:
print("没有找到当前版本信息,无法回滚")
return False
# 上一个版本号是当前版本减1
rollback_version = current_version - 1
# 检查上一个版本是否存在
try:
client.get_model_version(model_name, rollback_version)
except Exception as e:
print(f"上一个版本v{rollback_version}不存在,无法回滚:{str(e)}")
return False
# 部署上一个版本
if deploy_model(model_name, rollback_version, service_port):
# 更新当前版本文件
with open("current_version.txt", "w") as f:
f.write(str(rollback_version))
print(f"回滚成功,当前版本为v{rollback_version}")
return True
else:
print("回滚失败")
return False
# 主流程:模拟模型训练完,自动部署新模型,出错就回滚
if __name__ == "__main__":
MODEL_NAME = "house-price-prediction"
SERVICE_PORT = 8000
# 获取最新的模型版本
registered_model = client.get_registered_model(MODEL_NAME)
latest_version = registered_model.latest_versions[0].version
print(f"准备部署最新模型v{latest_version}")
# 先备份当前版本(如果有的话)
try:
with open("current_version.txt", "r") as f:
old_version = f.read().strip()
with open("old_version.txt", "w") as f:
f.write(old_version)
except FileNotFoundError:
pass
# 部署新模型
deploy_success = deploy_model(MODEL_NAME, latest_version, SERVICE_PORT)
if deploy_success:
# 更新当前版本文件
with open("current_version.txt", "w") as f:
f.write(str(latest_version))
print("新模型部署完成,流程结束")
else:
# 部署失败,回滚到上一个版本
print("新模型部署失败,开始回滚")
rollback(MODEL_NAME, SERVICE_PORT)
这个程序的主流程是:先获取最新的模型版本,然后部署它,如果部署成功就更新当前版本的记录;如果部署失败,就自动回滚到之前的版本。你可以把这个程序和训练平台连起来,只要训练平台训练完模型并推到MLflow,就自动触发这个程序,实现全自动化。
四、技术的应用场景、优缺点和注意事项
4.1 应用场景
这个方案适合很多AI项目的部署需求,比如: 第一,模型迭代频繁的项目,比如推荐系统的模型,每周都要更新,用这个方案可以自动部署,不用人管; 第二,需要管理多个模型的项目,比如一个平台要给不同的业务提供不同的模型服务,用MLflow可以统一管理所有模型的版本和部署; 第三,对部署可靠性要求高的项目,比如医疗、金融的模型,出错了要能快速回滚,这个方案的自动回滚功能刚好能满足。
4.2 技术优缺点
优点主要有三个: 第一,MLflow本身是开源的,不用花钱,而且功能很全,从模型管理到部署都有,不用自己搭很多系统; 第二,CLI和REST API的组合很灵活,简单的操作可以用CLI,复杂的自动化可以用REST API,适配不同的需求; 第三,MLflow的模型包是标准化的,不管你用什么框架训练的模型,打包之后部署的方式都是一样的,不用为不同的模型写不同的部署脚本。
缺点也有两个: 第一,MLflow本身的部署服务是基于Python的,对高并发的场景支持不够好,比如每秒要处理上万次请求的话,可能需要把MLflow的模型导出到更专业的服务框架(比如TensorFlow Serving、TorchServe); 第二,MLflow的监控功能比较基础,只能看服务的基本状态,要做更细的监控(比如模型的准确率变化、请求延迟),还需要搭配其他工具(比如Prometheus、Grafana)。
4.3 注意事项
用这个方案的时候,有几个地方要特别注意: 第一,模型包的依赖要匹配,比如你训练模型的时候用的是scikit-learn 1.3.0,部署的时候也要用同一个版本,不然可能会出现“模型加载失败”的问题,MLflow的模型包会记录依赖,部署的时候尽量用它记录的依赖; 第二,服务的资源配置要合理,比如每个模型服务需要多少CPU、内存,要根据实际情况调整,不然会出现服务卡顿或者崩溃的情况; 第三,版本管理要规范,比如每个模型版本的参数、训练数据要记录清楚,不然出问题的时候不知道哪个版本是对的; 第四,生产环境不要用本地的MLflow服务,要把MLflow的后端存在专业的数据库(比如PostgreSQL),模型存在云存储(比如S3、OSS),这样更稳定,也能支持多节点的部署。
五、文章总结
这篇文章讲了怎么用MLflow的CLI和REST API来实现模型部署流水线的自动化控制,从基础的MLflow服务启动,到模型上传、部署,再到出错回滚,都给了完整的例子。这个方案的核心是把人工操作的步骤,变成可以自动跑的流程,既提高了部署的效率,又减少了人工出错的概率。
当然,这个方案只是一个基础的实现,实际生产环境中还可以根据需求扩展,比如加上模型的A/B测试(同时部署两个版本的模型,测试哪个效果好)、服务的弹性伸缩(根据请求量自动调整服务的资源)、更完善的监控和告警(服务异常的时候自动发短信、邮件)。但不管怎么扩展,核心的思路都是一样的:用MLflow管理模型,用CLI和REST API控制部署流程,实现自动化。
评论
围绕“使用MLflow CLI与REST API完成模型部署流水线的自动化控制”参与讨论