使用MLflow在10分钟内将机器学习模型部署到生产中

3,059 阅读2分钟

我是在一周前接触到MLflow的,经过一些测试,我认为它是今年的SW。这可能是受我目前正在研究机器学习模型的产品化的影响。

因此,我将向你展示如何在生产环境中设置MLflow,就像David和我为我们的机器学习项目设置的那样。

追踪服务器的设置

追踪服务器是MLflow的用户界面元存储**。**你可以通过这个Web应用程序检查任何运行状态,并将模型的输出和配置集中在一个地方。

我们需要配置的第一件事是环境。

环境

让我们创建一个新的Conda环境,因为它将是安装MLflow的地方。

conda create -n mlflow_env 
conda activate mlflow_env

然后我们要安装MLflow库。

conda install python 
pip install mlflow

运行下面的命令来检查安装是否成功。

mlflow --help

Postgres

我们希望我们的Traking服务器有一个Postgres数据库,作为存储元数据的后台,所以第一步将是安装PostgreSQL。

sudo apt-get install postgresql postgresql-contrib postgresql-server-dev-all

检查连接到数据库的安装情况。

sudo -u postgres psql

安装成功后,让我们为 "追踪 "服务器创建一个用户和一个数据库。

CREATE DATABASE mlflow;
CREATE USER mlflow WITH ENCRYPTED PASSWORD 'mlflow';
GRANT ALL PRIVILEGES ON DATABASE mlflow TO mlflow;

由于我们需要从Python与Postgres进行交互,所以需要安装psycopg2库。然而,为了确保安装成功,我们需要在之前安装gcc linux包。

sudo apt install gcc 
pip install psycopg2

最后一步将是在我们的本地机器上为我们的跟踪服务器创建一个目录,以便在那里记录机器学习模型和其他工件。记住,Postgres数据库只用于存储有关这些模型的元数据(成像将模型或虚拟环境添加到数据库)。这个目录被称为工件URI。

mkdir ~/mlruns

运行

现在一切都设置好了,可以运行跟踪服务器了。然后写下以下命令。

mlflow server --backend-store-uri postgresql://mlflow:mlflow@localhost/mlflow --default-artifact-root file:/home/your_user/mlruns -h 0.0.0.0 -p 8000

现在,跟踪服务器应该有一个如下的URL:http://0.0.0.0:8000[。](http://0.0.0.0:8000/)但是,如果你按下Ctrl-C或者退出终端,服务器就会停机。

生产

如果你想让Tracking服务器在重启后仍能正常运行,并且对故障有弹性,那么把它作为一个systemd服务运行是非常有用的。

你需要进入/etc/systemd/system文件夹,创建一个名为mlflow-tracking.service的新文件,内容如下。

[Unit]
Description=MLflow tracking server
After=network.target 
[Service]
Restart=on-failure
RestartSec=30
ExecStart=/bin/bash -c 'PATH=/path_to_your_conda_installation/envs/mlflow_env/bin/:$PATH exec mlflow server --backend-store-uri postgresql://mlflow:mlflow@localhost/mlflow --default-artifact-root file:/home/your_user/mlruns -h 0.0.0.0 -p 8000' 
[Install]
WantedBy=multi-user.target

之后,你需要用以下命令来激活和启用该服务。

sudo systemctl daemon-reload 
sudo systemctl enable mlflow-tracking 
sudo systemctl start mlflow-tracking

用下面的命令检查一切是否按预期进行。

sudo systemctl status mlflow-tracking

现在你可以重新启动你的机器,MLflow跟踪服务器将在这次重启后启动并运行。

为了在这个跟踪服务器下开始跟踪一切,有必要在.bashrc上设置以下环境变量。

export MLFLOW_TRACKING_URI='http://0.0.0.0:8000'

记住,要用激活这个变化。

. ~/.bashrc

在生产中服务机器学习模型

一旦跟踪服务器启动,并且MLFLOW_TRACKING_URI在.bashrc中指向它,就该把你的模型投入生产了。

让我们开始创建生产环境来运行ML模型。

环境

conda create -n production_env 
conda activate production_env 
conda install python 
pip install mlflow 
pip install sklearn

然后,让我们从官方资源库中克隆一个例子来展示如何提升模型。

Github 示例

mlflow run git@github.com:databricks/mlflow-example.git -P alpha=0.5

这个运行将在你的跟踪服务器中产生一个新的条目http://0.0.0.0:8000,同时还有一个新的文件夹,模型和配置都存储在其中(~/mlruns/0/some_uuid)。让我们来检查一下。

ls -al ~/mlruns/0

从前面的输出中获取与执行有关的uuid,并在下面一行中用它替换字符串 "your_model_id"(当然,你可以在跟踪服务器中搜索uuid来完成)。

mlflow models serve -m ~/mlruns/0/your_model_id/artifacts/model -h 0.0.0.0 -p 8001

你刚才所做的是将你的模型作为你的服务器IP和端口8001的HTTP端点(注意不要有任何服务在那里监听),这样它就准备好接收传入的数据以返回预测结果。然后你可以用一个简单的curl命令查询你的模型。

curl -X POST -H "Content-Type:application/json; format=pandas-split" --data '{"columns":["alcohol", "chlorides", "citric acid", "density", "fixed acidity", "free sulfur dioxide", "pH", "residual sugar", "sulphates", "total sulfur dioxide", "volatile acidity"],"data":[[12.8, 0.029, 0.48, 0.98, 6.2, 29, 3.33, 1.2, 0.39, 75, 0.66]]}' http://0.0.0.0:8001/invocations

使用请求模块的Python或任何编程语言也可以用来获取预测结果,因为HTTP协议是与语言无关的。

import requests 
host = '0.0.0.0'
port = '8001' 
url = f'http://{host}:{port}/invocations' 
headers = {'Content-Type': 'application/json',} 
# test_data is a Pandas dataframe with data for testing the ML model
http_data = test_data.to_json(orient='split') 
r = requests.post(url=url, headers=headers, data=http_data) 
print(f'Predictions: {r.text}')

生产

最后,如果你想在生产中提供服务,你唯一需要做的就是添加systemd配置。

[Unit]
Description=MLFlow model in production 
After=network.target  
[Service]
Restart=on-failure RestartSec=30
Environment=MLFLOW_TRACKING_URI=http://host_ts:port_ts 
Environment=MLFLOW_CONDA_HOME=/path_to_your_conda_installation 
ExecStart=/bin/bash -c 'PATH=/path_to_your_conda_installation/envs/mlinproduction_env/bin/:$PATH exec mlflow models serve -m path_to_your_model -h host -p port' 
[Install]
WantedBy=multi-user.target