机器学习不是一个单向的pipeline,而是一个迭代的循环。其中包括四大部分:数据预处理、模型训练、模型部署、数据更新。
行业痛点:
MLflow是一个管理机器学习生命周期的开源平台( Github项目地址),直面行业痛点。
接下来对MLflow的使用分为三个流程介绍:参数追踪、工程、模型
使用参数追踪功能前需要指定追踪服务器,默认情况下单机启动mlflow本机将作为参数服务器,默认uri为http://localhost:5000。如果参数服务器部署在远端,参数服务器可以收集多台client端运行得到的参数。
启动server命令行如下:
mlflow server [OPTIONS]
mlflow server \
--backend-store-uri \
--default-artifact-root \
--host \
--port \
--workers \
--gunicorn-opts
参数追踪能选择性记录入口程序的参数和性能指标(如模型的超参、模型性能指标、业务评价指标等),理论上入口程序中暴露的任何参数和指标都可以记录,使用者可以依据需求灵活记录需要的指标。
使用tracking记录参数是代码侵入式的,在最开始需要指定追踪服务器的uri、实验的名字、选择性添加实验标签(标签必须是key : value形式,string类型)
下面是示例实验的配置:
mlflow.set_tracking_uri("http://127.0.0.1:5000/")
mlflow.create_experiment("MLflowProject")
mlflow.set_tag("实验类型", "存模型和部署服务")
下面的代码是一个记录黑盒调参结果的demo:
# hyperopt黑盒调参
def mlflow_hyperopt(data_cleaner):
train_data, test_data, eva_data = data_cleaner.do_job()
lr = LogisticRegressionTrainer(train_data, test_data, Processing.SEPARATE.value)
def objective(args):
log_reg = LogisticRegression(C=args["C"], max_iter=int(args["max_iter"]),
solver="lbfgs",
class_weight={0: 0.9, 1: 0.1})
log_reg.fit(lr.get_x_train().values, lr.get_y_train().values.ravel())
y_pred = log_reg.predict(lr.get_x_test())
return -accuracy_score(lr.get_y_test().values.ravel(), y_pred)
space = {"max_iter": hp.choice("max_iter", range(50, 250)), # 确定参数搜索范围
"C": hp.uniform("C", 0.1, 1)}
max_evals = 20
algo = tpe.suggest # 选择寻参函数
best = fmin(objective, space, algo=algo, max_evals=max_evals, verbose=1)
# mlflow代码入侵部分
# 记录黑盒调参的最优参数和结果
with mlflow.start_run(run_name='V0.0.4', nested=True):
mlflow.log_params(best)
mlflow.log_param("max_evals", str(max_evals))
mlflow.log_metric('accuracy', abs(objective(best)))
代码第21行用’with’开头调用start_run()表示tracking开始,用这种方式不需要再使用end_run()去终止当前实验。
start_run(run_id=None, experiment_id=None, run_name=None, nested=False)
log_param(key, value)
log_params(params)
log_metric(key, value, step=None)
log_metrics(metrics, step=None)
MLflow支持类sql的方式,依据实验标签或者实验结果对多次实验进行筛选(可以参考下面两个图示的操作)。此外MLflow还支持简单的可视化实验结果对比,这部分功能可以在实践中慢慢尝试和摸索。
当然除了UI筛选,MLflow还支持java和python使用api的方式对实验结果筛选。
注意:工程依赖环境有多种选择,以下案例工程均以conda作为依赖环境
构建MLflow工程只需要在原始工程根目录下添加MLproject和conda.yaml两个文件。MLproject负责记录这个项目的主要信息,conda.yaml记录项目依赖环境。
name: My Project
conda_env: conda.yaml
entry_points:
main:
parameters:
data_file: path
regularization: {type: float, default: 0.1}
command: "python train.py -r {regularization} {data_file}"
validate:
parameters:
data_file: path
command: "python validate.py {data_file}
如上MLproject示例文件所示,文件包含:
name: sklearn-example
channels:
- defaults
dependencies:
- python==3.6.1
- pandas==0.20.3
- scipy==1.3.1
- numpy==1.17.2
- scikit-learn==0.21.3
- matplotlib==2.0.2
- pip:
- mlflow>=1.3
- hyperopt==0.2.2
如上conda.yaml示例文件所示,文件包含:
$ conda env export --name=environment_name > conda.yaml
目前支持工程本地运行和git运行,本质上二者并无区别,使用git运行工程时会将整个工程从远程仓库拖拽到本地的临时路径中。建议使用git管理工程项目,方便版本管理与实验结果对比。
运行工程可以使用api也可以使用命令行的方式。
在cmd下使用 mlflow run 命令即可实现任务的提交,下面是一个提交运行的示例:
$ mlflow run file:///Users/lwb/.git/LogisticRegressionMLproject -v 8142edf2b2d1acb94e513d9ce1df12ebee511d3e -P C=1.0 -P class_weight=balanced --no-conda
提交任务的option含义如下:
MLflow Models相关文档对Models模块的定义为:这是一套标准格式来对模型结果进行打包,并可以被下游工具(如在线REST API服务和Apache Spark的批处理)所使用。
目前MLflow支持主流框架的模型格式,即下文提到的模型flavor参数,目前支持的flavor有如下几种:
在tracking中使用api即可完成对模型文件的存储,下例是使用sk-learn风格对模型文件存储:
mlflow.sklearn.log_model(model, "my_model")
mlflow.sklearn.save_model(model, "my_model")
使用任一方式均可
模型存储地址默认为工程任务提交路径下 ./mlruns 文件夹下,也可以通过 --default-artifact-root 参数指定模型文件存储在hdfs等共享文件夹下。
将模型文件放在工程artifacts文件下可以看到模型文件包含:
MLflow支持在artifacts路径下使用ui点击实现模型部署,生成模型服务如下例所示:
目前ui部署存在bug:不支持本地路径artifacts下的模型部署
目前可以使用数据库存储的解决案例,但是该本部分依旧需要官方给出具体解决方案。
命令行下serve部署
启动模型serve命令行如下:
mlflow models serve [OPTIONS]
mlflow models serve \
--model-uri \
--host \
--port \
--workers \
--no-conda
df = df[feature_headers].head(3)
msg = df.to_json(orient='split')
print(msg)
url = "http://0.0.0.0:8080/invocations"
headers = {'content-type': 'application/json; format=pandas-split'}
respond = requests.request("POST", url, data=msg, headers=headers)
print("predict: ", respond.json())
注意:发送数据的json格式与request中的字段格式一致
在命令行下使用模型文件能进行数据的批量预测,批量预测命令行如下:
mlflow models predict [OPTIONS]
mlflow models predict \
--model-uri \
--input-path \
--output-path \
--content-type \
--json-format \
--no-conda
spark_df = spark.createDataFrame(df)
pyfunc_udf = mlflow.pyfunc.spark_udf(spark, 'runs:/dcba50ddac7843bf9d371e270baf674d/models')
spark_df = spark_df.withColumn("prediction", pyfunc_udf('features'))
print(spark_df.show())
该种方法比较适用于需要大批量预测的场景。