ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

MLOps Zoomcamp 第 2 章实战:用 MLflow 做实验跟踪、模型管理与模型注册表

2026/9/14 17:14:32 拓冰建站 浏览量
MLOps Zoomcamp 第 2 章实战:用 MLflow 做实验跟踪、模型管理与模型注册表 MLOps Zoomcamp 第 2 章实战用 MLflow 做实验跟踪、模型管理与模型注册表【免费下载链接】mlops-zoomcampFree MLOps course from DataTalks.Club. Register here to get notified about the next cohort项目地址: https://gitcode.com/GitHub_Trending/ml/mlops-zoomcampMLOps ZoomcampDataTalks.Club 免费 MLOps 课程第 2 章的主题是实验跟踪Experiment Tracking与模型管理Model Management。本章以 NYC Green Taxi 行程时长预测为贯穿案例讲解如何用 MLflow 记录实验参数、指标与模型工件以及如何用 Model Registry 管理模型版本。读完后你将掌握本地启动 MLflow 跟踪的三种典型部署场景本地文件系统 / 本地 tracking server / 远程 AWS tracking server、实验日志的完整代码写法、MlflowClient注册表操作以及 MLflow 2.9 之后 stage 弃用、改用 alias 的迁移方式。2.1 实验跟踪简介实验跟踪解决的是机器学习研发中的核心痛点模型调参过程不可复现、结果不可追溯、参数-指标-代码-数据之间的对应关系靠人脑记忆。MLflow 将一次训练抽象为一个Run把以下四类信息结构化地持久化下来Parameters参数如alpha、max_depth、数据路径Metrics指标如rmse、accuracyTags标签如developer、model类型标记Artifacts工件训练好的模型文件、preprocessor 等任意二进制文件。一个 Experiment 下可以挂任意多个 Run配合 Web UI 即可横向对比多次实验这正是后续模型注册、部署的前提。2.2 快速上手 MLflow本课程的运行环境说明视频示例中讲师使用 VS Code 中的 Jupyter 在本地运行全部实验如果第 1 章中已经搭建了 AWS VM也可以继续在 VM 上用浏览器访问 Jupyter两者没有实质区别。本章依赖来自 requirements.txtmlflow jupyter scikit-learn pandas seaborn hyperopt xgboost fastparquet boto3可以看到课程覆盖了实验跟踪全链路所需的技术栈mlflow本身、scikit-learn/xgboost作为建模对象、hyperopt做超参数搜索、boto3支撑后文 AWS 场景的 S3 工件存储。2.3 用 MLflow 做实验跟踪核心代码在 duration-prediction.ipynb。先设置跟踪 URI 和实验名import mlflow mlflow.set_tracking_uri(sqlite:///mlflow.db) mlflow.set_experiment(nyc-taxi-experiment)这里使用sqlite:///mlflow.db作为后端存储——不需要单独部署数据库服务一个本地文件即可承载元数据适合个人开发场景。数据准备与特征工程数据是 NYC Green Taxi 2021 年 1、2 月的行程记录1 月训练、2 月验证目标是行程时长分钟def read_dataframe(filename): df pd.read_csv(filename) df.lpep_dropoff_datetime pd.to_datetime(df.lpep_dropoff_datetime) df.lpep_pickup_datetime pd.to_datetime(df.lpep_pickup_datetime) df[duration] df.lpep_dropoff_datetime - df.lpep_pickup_datetime df.duration df.duration.apply(lambda td: td.total_seconds() / 60) df df[(df.duration 1) (df.duration 60)] categorical [PULocationID, DOLocationID] df[categorical] df[categorical].astype(str) return df df_train read_dataframe(./data/green_tripdata_2021-01.csv) df_val read_dataframe(./data/green_tripdata_2021-02.csv) df_train[PU_DO] df_train[PULocationID] _ df_train[DOLocationID] df_val[PU_DO] df_val[PULocationID] _ df_val[DOLocationID] categorical [PU_DO] numerical [trip_distance] dv DictVectorizer() X_train dv.fit_transform(df_train[categorical numerical].to_dict(orientrecords)) X_val dv.transform(df_val[categorical numerical].to_dict(orientrecords)) y_train df_train[duration].values y_val df_val[duration].values注意两处细节时长做了[1, 60]分钟的异常值过滤上下车位置被拼接成单一特征PU_DO如178_264以降低特征组合爆炸。记录一次完整实验参数、指标、工件以 Lasso 回归为例mlflow.start_run()上下文内记录参数、指标和工件with mlflow.start_run(): mlflow.set_tag(developer, cristian) mlflow.log_param(train-data-path, ./data/green_tripdata_2021-01.csv) mlflow.log_param(valid-data-path, ./data/green_tripdata_2021-02.csv) alpha 0.1 mlflow.log_param(alpha, alpha) lr Lasso(alpha) lr.fit(X_train, y_train) y_pred lr.predict(X_val) rmse mean_squared_error(y_val, y_pred, squaredFalse) mlflow.log_metric(rmse, rmse) mlflow.log_artifact(local_pathmodels/lin_reg.bin, artifact_pathmodels_pickle)几个要点mlflow.log_param/mlflow.log_metric是手工记录的最小单元键值自由命名后文search_runs的过滤查询就是基于这些键mlflow.set_tag用于标注非结构化元信息如开发者、模型族不参与数值排序mlflow.log_artifact把本地模型文件pickle 序列化的(DictVectorizer, Lasso)元组上传到工件存储artifact_path决定其在 UI 中的目录mean_squared_error(..., squaredFalse)即 RMSE作为统一的对比指标。超参数搜索Hyperopt XGBoost 逐试验记录第 2 章的进阶内容是在hyperopt的fmin搜索循环里每评估一组超参数就开一个 MLflow Run让 50 次搜索天然变成 50 个可对比、可复现的 Runfrom hyperopt import fmin, tpe, hp, STATUS_OK, Trials from hyperopt.pyll import scope train xgb.DMatrix(X_train, labely_train) valid xgb.DMatrix(X_val, labely_val) def objective(params): with mlflow.start_run(): mlflow.set_tag(model, xgboost) mlflow.log_params(params) booster xgb.train( paramsparams, dtraintrain, num_boost_round1000, evals[(valid, validation)], early_stopping_rounds50 ) y_pred booster.predict(valid) rmse mean_squared_error(y_val, y_pred, squaredFalse) mlflow.log_metric(rmse, rmse) return {loss: rmse, status: STATUS_OK} search_space { max_depth: scope.int(hp.quniform(max_depth, 4, 100, 1)), learning_rate: hp.loguniform(learning_rate, -3, 0), reg_alpha: hp.loguniform(reg_alpha, -5, -1), reg_lambda: hp.loguniform(reg_lambda, -6, -1), min_child_weight: hp.loguniform(min_child_weight, -1, 3), objective: reg:linear, seed: 42 } best_result fmin( fnobjective, spacesearch_space, algotpe.suggest, max_evals50, trialsTrials() )这个模式的工程价值在于搜索算法只返回最优参数而 MLflow 保留了全部中间试验可以在 UI 中按metrics.rmse排序排查哪些区域表现差。找到最优参数后再单独开一个 Run 记录最终胜出配置的完整训练并注册模型with mlflow.start_run(): best_params { learning_rate: 0.09585355369315604, max_depth: 30, min_child_weight: 1.060597050922164, objective: reg:linear, reg_alpha: 0.018060244040060163, reg_lambda: 0.011658731377413597, seed: 42 } mlflow.log_params(best_params) booster xgb.train( paramsbest_params, dtraintrain, num_boost_round1000, evals[(valid, validation)], early_stopping_rounds50 ) y_pred booster.predict(valid) rmse mean_squared_error(y_val, y_pred, squaredFalse) mlflow.log_metric(rmse, rmse) with open(models/preprocessor.b, wb) as f_out: pickle.dump(dv, f_out) mlflow.log_artifact(models/preprocessor.b, artifact_pathpreprocessor) mlflow.xgboost.log_model(booster, artifact_pathmodels_mlflow)两处值得注意笔记本显式调用mlflow.xgboost.autolog(disableTrue)关闭 XGBoost 自动日志避免自动记录与手工记录产生冗余 Run 干扰mlflow.xgboost.log_model与log_artifact的区别前者按 MLflow 模型格式MLmodel 描述文件 conda/requirements 环境信息保存可被mlflow.models.load_model跨环境直接加载后者只是裸文件传输。用 autolog 批量跟踪多种模型对于 scikit-learn 生态mlflow.sklearn.autolog()一行即可在fit/predict时自动记录参数、指标与模型适合快速横向比较多模型from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor, ExtraTreesRegressor from sklearn.svm import LinearSVR mlflow.sklearn.autolog() for model_class in (RandomForestRegressor, GradientBoostingRegressor, ExtraTreesRegressor, LinearSVR): with mlflow.start_run(): mlflow.log_param(train-data-path, ./data/green_tripdata_2021-01.csv) mlflow.log_param(valid-data-path, ./data/green_tripdata_2021-02.csv) mlflow.log_artifact(models/preprocessor.b, artifact_pathpreprocessor) mlmodel model_class() mlmodel.fit(X_train, y_train) y_pred mlmodel.predict(X_val) rmse mean_squared_error(y_val, y_pred, squaredFalse) mlflow.log_metric(rmse, rmse)对比上述三段代码可以看出本课程的记录策略梯度手工 API最细粒度→ 框架集成 APImlflow.xgboost/mlflow.sklearn→ autolog最省代码按团队需要选择。2.4 模型管理Model Management模型管理的目标是让训练产出的模型可被消费不只是存一个 pickle 文件而是保存为带元数据的 MLflow 模型并能被后续程序按 run 定位、加载。前面mlflow.xgboost.log_model(booster, artifact_pathmodels_mlflow)已经完成了保存一侧消费侧则通过runs:/run_id/model这类 URI 定位模型这也是下一节register_model的入参格式。从笔记本结构看模型保存路径有三类并行存在models/lin_reg.binpickle 裸文件、models/preprocessor.b向量化工具作为 artifact 单独登记、models_mlflowMLflow 格式模型——分别对应部署脚本直接加载、预处理器版本绑定、注册表管理三种消费方式。2.5 模型注册表Model RegistryModel Registry 在实验跟踪之上增加了一层命名与版本治理把某个 Run 里保存的模型注册为一个命名模型如nyc-taxi-regressor的一个 version从而支持版本比较、阶段流转与部署决策。核心代码在 model-registry.ipynb。用 MlflowClient 操作跟踪服务与注册表MlflowClient同时面向 Tracking Server实验/Run和 Registry Server注册模型/版本from mlflow.tracking import MlflowClient MLFLOW_TRACKING_URI sqlite:///mlflow.db client MlflowClient(tracking_uriMLFLOW_TRACKING_URI) client.create_experiment(namemy-cool-experiment)按条件查找 Run例如找出 RMSE 小于 7 的前 5 个活跃 Runfrom mlflow.entities import ViewType runs client.search_runs( experiment_ids1, filter_stringmetrics.rmse 7, run_view_typeViewType.ACTIVE_ONLY, max_results5, order_by[metrics.rmse ASC] )filter_string使用类 SQL 语法这正是前文坚持用mlflow.log_metric(rmse, ...)统一命名指标键的回报——指标命名不一致时这类结构化查询就无法工作。注册模型版本与阶段流转把某个 Run 中的模型注册为新版本run_id b8904012c84343b5bf8ee72aa8f0f402 model_uri fruns:/{run_id}/model mlflow.register_model(model_urimodel_uri, namenyc-taxi-regressor)然后可以查询最新版本、把版本流转到 Staging 阶段并补充描述model_name nyc-taxi-regressor latest_versions client.get_latest_versions(namemodel_name) for version in latest_versions: print(fversion: {version.version}, stage: {version.current_stage}) model_version 4 new_stage Staging client.transition_model_version_stage( namemodel_name, versionmodel_version, stagenew_stage, archive_existing_versionsFalse ) client.update_model_version( namemodel_name, versionmodel_version, descriptionfThe model version {model_version} was transitioned to {new_stage} on {date} )重要版本提示自MLflow 2.9 起模型注册表的 stage 概念已被弃用README 原文强调。应改用模型版本标签tags和别名aliases来表达 production / staging 等状态。例如用set_registered_model_alias(name, alias, version)代替transition_model_version_stage(name, version, stage)。上例代码对应课程早期版本若你在新版 MLflow 上执行需要按 alias 方式改写。用注册表挑选新的生产模型笔记本最后部分模拟部署工程师的决策场景加载 2021 年 3 月的测试集green_tripdata_2021-03.csv从注册表拉取nyc-taxi-regressor的多个版本从 MLflow 下载当时保存的DictVectorizer工件逐版本计算测试集 RMSE据此决定生产版本是否更新。这条从注册表拉模型 → 绑定 preprocessor → 离线评测 → 切换版本的流程就是后续第 4 章部署环节的直接输入。2.6 实战三种典型部署场景running-mlflow-examples/目录下有三个 notebook分别对应课程中反复出现的三种 MLflow 部署形态是本章最有实操价值的部分。场景 1单人开发无 tracking server对应文件 scenario-1.ipynb。配置无 tracking server后端存储为本地文件系统工件存储为本地文件系统直接用mlflow ui查看。import mlflow print(ftracking URI: {mlflow.get_tracking_uri()}) mlflow.search_experiments() mlflow.set_experiment(my-experiment-1) with mlflow.start_run(): X, y load_iris(return_X_yTrue) params {C: 0.1, random_state: 42} mlflow.log_params(params) lr LogisticRegression(**params).fit(X, y) y_pred lr.predict(X) mlflow.log_metric(accuracy, accuracy_score(y, y_pred)) mlflow.sklearn.log_model(lr, artifact_pathmodel)注意此场景下模型注册表不可用——没有后端数据库承载注册表元数据from mlflow.tracking import MlflowClient from mlflow.exceptions import MlflowException client MlflowClient() try: client.search_registered_models() except MlflowException: print(Its not possible to access the model registry :()场景 2小团队共享本地 tracking server SQLite对应文件 scenario-2.ipynb。配置本地 tracking server后端存储 SQLite工件存储本地文件系统。先在终端启动服务mlflow server --backend-store-uri sqlite:///backend.db客户端指向该服务后即可使用完整注册表能力import mlflow mlflow.set_tracking_uri(http://127.0.0.1:5000) client MlflowClient(http://127.0.0.1:5000) client.search_registered_models() run_id client.search_runs(experiment_ids1)[0].info.run_id mlflow.register_model( model_urifruns:/{run_id}/models, nameiris-classifier )场景 3多人多模型远程 server PostgreSQL S3对应文件 scenario-3.ipynb。配置远程 tracking serverEC2后端存储 PostgreSQL工件存储 S3。这是生产级团队的标准形态AWS 侧的完整搭建步骤见下一节。import mlflow import os os.environ[AWS_PROFILE] # 填入你的 AWS profile TRACKING_SERVER_HOST # 填入 EC2 实例的公网 DNS mlflow.set_tracking_uri(fhttp://{TRACKING_SERVER_HOST}:5000) print(ftracking URI: {mlflow.get_tracking_uri()}) mlflow.search_experiments()三个场景的日志记录代码完全一致同一段 irisLogisticRegression实验只有set_tracking_uri与后端不同——这体现了 MLflow 的设计意图跟踪 API 与存储后端解耦迁移部署形态不需要改业务代码。在 AWS 上搭建远程 tracking servermlflow_on_aws.md 给出了完整步骤RDSPostgreSQL作后端存储 S3 桶作工件存储 EC2 跑 tracking server。创建 AWS 账号新账号有免费额度但注意免费层之外的用量会计费。启动 EC2 实例选择免费额度实例类型如t2.micro Amazon Linux 2Kernel 5.10, SSD Volume Type创建新的 key pair 用于 SSH 连接编辑安全组放行SSH22 端口和HTTP5000 端口MLflow UI。创建 S3 桶作为工件存储。注意桶名在全 AWS 分区内全局唯一重名时换名重试如mlflow-artifacts-remote-2。创建 RDS PostgreSQL 数据库引擎选 PostgreSQL Free tier 模板实例主用户名设为mlflow勾选 Auto generate a password在 Additional configuration 中指定初始数据库名。点击 launch 后自动生成的密码只显示一次务必保存。记录四项关键信息master username、password、initial database name、endpoint。随后在 RDS 控制台的 Connectivity security 中修改 VPC 安全组添加入站规则允许来自 EC2 安全组的 5432 端口 PostgreSQL 连接数据库名默认为postgres。在 EC2 上安装依赖并启动服务sudo yum update pip3 install mlflow boto3 psycopg2-binary aws configure # 输入 AWS 凭据启动 tracking server占位符替换为第 4 步记录的值mlflow server -h 0.0.0.0 -p 5000 \ --backend-store-uri postgresql://DB_USER:DB_PASSWORDDB_ENDPOINT:5432/DB_NAME \ --default-artifact-root s3://S3_BUCKET_NAME启动前先验证实例能访问 S3 桶aws s3 ls应能列出该桶。-h 0.0.0.0使服务监听所有网卡对外可达-p 5000与安全组放行端口一致。从本地浏览器访问http://EC2_PUBLIC_DNS:5000公网 DNS 在 EC2 控制台的实例详情中查看。这套配置中--backend-store-uri与--default-artifact-root两个参数是理解远程部署的关键前者决定元数据实验/Run/注册表落在 PostgreSQL后者决定大文件模型、preprocessor落在 S3两者分离正是生产环境的标准架构。2.7 MLflow 的收益、局限与替代方案从本章代码可以归纳 MLflow 的收益边界收益统一的结构化日志 跨框架sklearn/xgboost记录 API 存储后端可插拔文件/SQLite/PostgreSQL本仓库三个场景 notebook 即为证明 注册表版本治理局限由实现结构可推断MLflow 只覆盖训练→登记环节不包含调度需要第 3 章的 Prefect 编排和部署/监控第 4、5 章且 stage 概念自 2.9 起弃用带来的 API 迁移成本课程 README 专门提示了list_experiments→search_experiments的更名问题说明旧教程/笔记需核对版本替代课程同时提到 WB 等方案2023 届作业提供了wandb版本实现见 homework-wandb选型上可按团队既有工具链决定。2.8 本章作业2025 届的作业要求基于同样的 NYC Taxi 数据实现数据预处理、训练 MLflow 日志、Hyperopt 超参搜索、注册模型四个环节详见 cohorts/2025/02-experiment-tracking/homework.md配套骨架代码hpo.py、train.py、register_model.py与历年解答如 2024 届 solution可作为对照。参考文件索引内容路径模块大纲与视频索引02-experiment-tracking/README.md、meta.json实验跟踪主案例Lasso / HyperoptXGBoost / autologduration-prediction.ipynb注册表操作search_runs / register / stage 流转model-registry.ipynb三种部署场景示例scenario-1.ipynb、scenario-2.ipynb、scenario-3.ipynbAWS 远程 tracking server 搭建mlflow_on_aws.md依赖清单requirements.txt2025 届作业homework.md【免费下载链接】mlops-zoomcampFree MLOps course from DataTalks.Club. Register here to get notified about the next cohort项目地址: https://gitcode.com/GitHub_Trending/ml/mlops-zoomcamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考