第 92 课 - MLOps 基础:MLflow 与 DVC
学习目标
- 理解机器学习项目中实验可重复性与数据版本控制的重要性。
- 掌握使用 MLflow Tracking 记录实验参数、指标和模型。
- 掌握使用 DVC (Data Version Control) 管理大型数据集和模型文件的版本。
- 了解如何将 MLflow 与 DVC 结合,构建一个简单、可复现的 MLOps 流程。
核心概念
1. 为什么需要这些工具?
想象一下,你和你的团队在进行一个机器学习项目。你尝试了不同的模型架构、超参数和数据预处理方法。一周后,你想复现上周表现最好的那个模型,却发现已经记不清当时的参数设置,或者训练用的数据文件已经被覆盖修改了。这就是典型的“实验混乱”。
MLOps (Machine Learning Operations) 的目标就是将 DevOps 的理念引入机器学习,解决这些问题。MLflow 和 DVC 是实现 MLOps 基础流程的两个关键工具。
2. MLflow:实验跟踪与生命周期管理
MLflow 是一个开源平台,用于管理机器学习的整个生命周期。它最核心的组件是 MLflow Tracking。
- 它像一本“实验笔记本”:当你运行一次模型训练时,你可以使用 MLflow 记录:
- 参数 (Parameters):如学习率、树的最大深度等。
- 指标 (Metrics):如准确率、均方误差等。
- 模型文件 (Artifacts):如保存的模型 (.pkl, .h5)、混淆矩阵图片等。
- 数据集信息:记录使用的数据集的摘要或哈希值。
- 所有记录都保存在一个 实验 (Experiment) 下,你可以在 MLflow UI (一个本地网页界面) 中轻松对比、搜索和可视化不同运行的结果。
3. DVC:数据与模型的版本控制
Git 非常适合管理代码,但对于动辄几百MB甚至几个GB的数据集和模型文件就力不从心了。DVC 填补了这个空白。
- 它为大数据文件创建“指针”:DVC 会在你的 Git 仓库中创建一个很小的
.dvc文件,这个文件记录了大数据文件的 MD5 哈希值 和存储位置(本地或远程,如 S3、Google Cloud Storage)。 - 真正的数据存储在别处:数据文件本身存储在配置好的远程存储中。当你运行
dvc pull时,它会根据.dvc文件中的信息,从远程存储下载正确的数据版本。 - 它支持轻量级管道:你可以用
dvc.yaml文件定义一系列命令(如数据预处理、训练、评估),形成一个可复现的管道。
简单比喻:
- Git 管理你的“食谱”(代码)。
- DVC 管理你的“食材”(数据)和“成品”(模型),确保任何时候你都能拿到正确的食材。
- MLflow 管理你每次“烹饪”的记录(火候、调味料用量、成品口感)。
代码示例
下面的示例演示了如何将一个简单的 Scikit-learn 模型训练过程与 MLflow 和 DVC 结合。
第一步:安装必要的库
pip install mlflow scikit-learn pandas dvc
# 如果你有远程存储(如S3),可能还需要安装对应的库,例如:boto3 for AWS S3
第二步:项目结构
my_mlops_project/
├── .git/ # Git 仓库
├── data/ # 存放数据(DVC 将管理它)
│ └── iris.csv # 被 DVC 跟踪的文件
├── src/
│ └── train.py # 我们的训练脚本
├── dvc.yaml # DVC 管道定义(可选)
└── .dvc/ # DVC 缓存(自动生成)
第三步:示例训练代码 (src/train.py)
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, f1_score
import mlflow
import mlflow.sklearn
# 1. 准备数据
print("加载数据...")
# 假设数据由 DVC 管理,我们直接读取
data_path = "data/iris.csv" # 这个文件已被 DVC 跟踪
df = pd.read_csv(data_path)
X = df.drop('species', axis=1)
y = df['species']
# 2. 开始一次 MLflow 运行
print("开始 MLflow 运行...")
mlflow.set_experiment("Iris_Classification") # 设置实验名
with mlflow.start_run(run_name="RandomForest_Baseline"): # 使用 `with` 语句,确保运行正确结束
# 3. 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 4. 训练模型
n_estimators = 100
max_depth = 3
model = RandomForestClassifier(n_estimators=n_estimators, max_depth=max_depth, random_state=42)
model.fit(X_train, y_train)
# 5. 评估模型
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred, average='weighted')
# 6. 记录所有信息到 MLflow
print("记录参数和指标到 MLflow...")
mlflow.log_param("n_estimators", n_estimators)
mlflow.log_param("max_depth", max_depth)
mlflow.log_metric("accuracy", accuracy)
mlflow.log_metric("f1_score", f1)
# 记录模型本身
mlflow.sklearn.log_model(model, "random_forest_model")
# 记录数据集的信息(可选,但推荐)
mlflow.log_artifact(data_path, "data")
# 打印结果
print(f"运行完成!准确率: {accuracy:.4f}, F1分数: {f1:.4f}")
print(f"运行ID: {mlflow.active_run().info.run_id}")
print("请查看 MLflow UI: 运行 `mlflow ui` 在浏览器中查看结果。")
第四步:使用 DVC 管理数据文件
- 初始化 DVC (在项目根目录下):
git init # 如果还没有 Git 仓库 dvc init git add .dvc .dvcignore git commit -m "Initialize DVC" - 将数据文件添加到 DVC:
# 假设你已经将 iris.csv 放在了 data/ 目录下 dvc add data/iris.csv # 这会创建一个 data/iris.csv.dvc 文件,并将 data/iris.csv 加入 .gitignore - 配置远程存储 (以本地目录为例,实际中常用 AWS S3, GCS 等):
mkdir /tmp/dvcstorage # 作为示例远程存储 dvc remote add -d myremote /tmp/dvcstorage - 推送数据到远程存储:
dvc push - 将
.dvc文件提交到 Git:git add data/iris.csv.dvc .dvc/config git commit -m "Add Iris dataset with DVC tracking"
现在,你的项目同时使用了 Git (代码) + DVC (数据) + MLflow (实验记录)。新的开发者克隆仓库后,只需运行 dvc pull 就能获得训练数据。
实践练习
练习1:运行并探索 MLflow
运行上面的 train.py 脚本,然后启动 MLflow UI (mlflow ui),在浏览器中打开 http://localhost:5000。
- 任务:找到你刚才的运行记录,查看记录的参数、指标和模型。尝试点击模型“Artifacts”标签,查看保存的模型文件。
- 预期输出:能在 MLflow UI 中清晰看到一个名为“RandomForest_Baseline”的运行,包含所有设定的参数和指标。
练习2:使用 DVC 跟踪数据变更
- 在
data/目录下创建一个新的 CSV 文件iris_extended.csv(例如,添加一列新特征)。 - 使用
dvc add跟踪这个新文件。 - 修改
train.py中的data_path指向这个新文件。 - 运行训练脚本,并在 MLflow UI 中查看新的实验结果。
- 任务:对比两次运行的数据集版本(通过 MLflow 记录的数据 artifact)和模型性能。
- 预期输出:MLflow UI 中出现两次运行,可以对比新旧数据集对模型性能的影响。
练习3:设计一个简单管道(进阶)
- 创建一个
prepare_data.py脚本,读取data/iris.csv并进行标准化,输出data/iris_processed.csv。 - 修改
train.py读取data/iris_processed.csv。 - 创建一个
dvc.yaml文件,定义prepare_data和train两个阶段。
- 任务:运行
dvc repro来执行整个管道。 - 预期输出:DVC 自动按顺序运行两个脚本,并且整个流程是可复现的。
常见错误
- 忘记结束 MLflow 运行:如果不使用
with mlflow.start_run():或忘记调用mlflow.end_run(),运行记录可能不会被正确保存。始终建议使用with语句。 - DVC 文件路径错误:在
dvc.yaml或脚本中引用数据文件时,路径必须与.dvc文件记录的实际存储路径(相对于项目根目录)完全一致。 - 未设置 DVC 远程存储就执行
dvc push:会报错。确保先使用dvc remote add配置好远程存储。 - 混合管理数据和代码:试图用 DVC 管理小的配置文件或代码。DVC 应专用于管理大型二进制文件(数据、模型)。代码和小文件应始终用 Git 管理。
- MLflow 指标/参数名不一致:在多次运行中,如果使用不同的参数名(如
lr和learning_rate),将很难在 UI 中进行对比。请保持命名一致。
小结
本节课我们学习了构建机器学习项目工程化基础的两个关键工具:
- MLflow Tracking:解决了“实验记录”的问题,让我们能系统地记录、比较和检索每次训练的细节,是模型迭代和团队协作的基础。
- DVC:解决了“数据版本控制”的问题,通过与 Git 类似的语义(
add,push,pull,checkout)管理大型数据和模型文件,确保实验的可复现性。
将两者结合,我们得到了一个基本的 MLOps 工作流:
- 使用 DVC 管理数据和模型的版本。
- 使用 Git 管理代码和 DVC 的元数据文件(
.dvc)。 - 使用 MLflow 记录所有实验的参数、指标和产出物。
这套组合拳为后续更高级的实践,如自动化管道、模型注册表和持续部署,打下了坚实的基础。在下一课中,我们将转向机器学习的一个具体应用领域——自然语言处理(NLP)。