实验跟踪 #
MLflow Tracking 概述 #
MLflow Tracking 是 MLflow 的核心组件之一,用于记录、组织和查询机器学习实验。
text
┌─────────────────────────────────────────────────────────────┐
│ MLflow Tracking 架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 客户端 API │ │
│ │ ├── Python API (mlflow.*) │ │
│ │ ├── Java API │ │
│ │ ├── R API │ │
│ │ └── REST API │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Tracking Server │ │
│ │ ├── 接收实验数据 │ │
│ │ ├── 存储元数据 │ │
│ │ └── 提供 UI 和 API │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 存储层 │ │
│ │ ├── Backend Store (元数据) │ │
│ │ └── Artifact Store (工件) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
核心概念 #
Experiment(实验) #
python
import mlflow
experiment_id = mlflow.create_experiment(
name="my-experiment",
artifact_location="s3://my-bucket/experiments",
tags={
"project": "customer-churn",
"team": "data-science"
}
)
print(f"Experiment ID: {experiment_id}")
Run(运行) #
text
┌─────────────────────────────────────────────────────────────┐
│ Run 结构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Run ID: 唯一标识符 │
│ ├── abc123def456... │
│ │
│ Parameters: 超参数 │
│ ├── learning_rate: 0.01 │
│ ├── batch_size: 32 │
│ └── epochs: 100 │
│ │
│ Metrics: 评估指标 │
│ ├── accuracy: 0.95 │
│ ├── loss: 0.05 │
│ └── f1_score: 0.94 │
│ │
│ Artifacts: 输出文件 │
│ ├── model/ (模型文件) │
│ ├── plots/ (图表) │
│ └── data/ (数据) │
│ │
│ Tags: 标签 │
│ ├── model_type: RandomForest │
│ └── version: 1.0 │
│ │
│ Metadata: 元数据 │
│ ├── start_time: 2024-01-01 10:00:00 │
│ ├── end_time: 2024-01-01 10:05:00 │
│ ├── status: FINISHED │
│ └── user: data-scientist │
│ │
└─────────────────────────────────────────────────────────────┘
参数记录 #
基本参数记录 #
python
import mlflow
with mlflow.start_run():
mlflow.log_param("learning_rate", 0.01)
mlflow.log_param("batch_size", 32)
mlflow.log_param("epochs", 100)
mlflow.log_param("optimizer", "adam")
批量记录参数 #
python
import mlflow
with mlflow.start_run():
params = {
"learning_rate": 0.01,
"batch_size": 32,
"epochs": 100,
"optimizer": "adam",
"dropout": 0.5,
"hidden_units": 128
}
mlflow.log_params(params)
参数命名规范 #
text
┌─────────────────────────────────────────────────────────────┐
│ 参数命名最佳实践 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ✅ 推荐做法: │
│ ├── 使用小写字母和下划线 │
│ │ learning_rate, batch_size, hidden_units │
│ │ │
│ ├── 使用层级命名 │
│ │ model.learning_rate, optimizer.beta1 │
│ │ │
│ └── 保持一致性 │
│ 同类参数使用相同命名风格 │
│ │
│ ❌ 避免做法: │
│ ├── 使用特殊字符 │
│ │ learning-rate, batch.size │
│ │ │
│ ├── 过长的名称 │
│ │ this_is_a_very_long_parameter_name │
│ │ │
│ └── 不一致的命名 │
│ lr, learningRate, Learning_Rate │
│ │
└─────────────────────────────────────────────────────────────┘
指标追踪 #
基本指标记录 #
python
import mlflow
with mlflow.start_run():
mlflow.log_metric("accuracy", 0.95)
mlflow.log_metric("precision", 0.94)
mlflow.log_metric("recall", 0.96)
mlflow.log_metric("f1_score", 0.95)
时间序列指标 #
python
import mlflow
with mlflow.start_run():
for epoch in range(100):
train_loss = calculate_train_loss(epoch)
val_loss = calculate_val_loss(epoch)
mlflow.log_metric("train_loss", train_loss, step=epoch)
mlflow.log_metric("val_loss", val_loss, step=epoch)
指标历史记录 #
python
import mlflow
with mlflow.start_run():
mlflow.log_metric("accuracy", 0.80, step=1)
mlflow.log_metric("accuracy", 0.85, step=2)
mlflow.log_metric("accuracy", 0.90, step=3)
mlflow.log_metric("accuracy", 0.95, step=4)
指标类型 #
text
┌─────────────────────────────────────────────────────────────┐
│ 指标类型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 单值指标: │
│ ├── 最终结果指标 │
│ ├── accuracy, f1_score, auc │
│ └── 只记录最终值 │
│ │
│ 时间序列指标: │
│ ├── 训练过程指标 │
│ ├── loss, learning_rate, gradient_norm │
│ └── 每个 step 记录一次 │
│ │
│ 系统指标: │
│ ├── 资源使用情况 │
│ ├── cpu_usage, memory_usage, gpu_memory │
│ └── 自动或手动记录 │
│ │
└─────────────────────────────────────────────────────────────┘
工件存储 #
记录单个工件 #
python
import mlflow
with mlflow.start_run():
mlflow.log_artifact("config.yaml")
mlflow.log_artifact("model.pkl")
mlflow.log_artifact("results.json")
记录目录 #
python
import mlflow
with mlflow.start_run():
mlflow.log_artifacts("./outputs", artifact_path="outputs")
mlflow.log_artifacts("./plots", artifact_path="plots")
记录图表 #
python
import mlflow
import matplotlib.pyplot as plt
import seaborn as sns
with mlflow.start_run():
fig, ax = plt.subplots()
ax.plot([1, 2, 3, 4], [1, 4, 2, 3])
ax.set_xlabel('Epoch')
ax.set_ylabel('Loss')
fig.savefig("training_curve.png")
mlflow.log_artifact("training_curve.png")
plt.close(fig)
记录数据文件 #
python
import mlflow
import pandas as pd
with mlflow.start_run():
df = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
df.to_csv("sample_data.csv", index=False)
mlflow.log_artifact("sample_data.csv")
工件类型 #
text
┌─────────────────────────────────────────────────────────────┐
│ 工件类型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 模型文件: │
│ ├── model.pkl, model.joblib │
│ ├── model.h5, model.pt │
│ └── MLflow 模型目录 │
│ │
│ 配置文件: │
│ ├── config.yaml, config.json │
│ ├── hyperparameters.json │
│ └── requirements.txt │
│ │
│ 可视化文件: │
│ ├── training_curve.png │
│ ├── confusion_matrix.png │
│ └── feature_importance.png │
│ │
│ 数据文件: │
│ ├── sample_data.csv │
│ ├── predictions.json │
│ └── evaluation_results.json │
│ │
│ 文档文件: │
│ ├── README.md │
│ ├── model_card.md │
│ └── experiment_notes.txt │
│ │
└─────────────────────────────────────────────────────────────┘
标签管理 #
设置标签 #
python
import mlflow
with mlflow.start_run():
mlflow.set_tag("model_type", "RandomForest")
mlflow.set_tag("dataset", "customer-churn")
mlflow.set_tag("team", "data-science")
mlflow.set_tag("priority", "high")
批量设置标签 #
python
import mlflow
with mlflow.start_run():
tags = {
"model_type": "RandomForest",
"dataset": "customer-churn",
"team": "data-science",
"priority": "high",
"version": "1.0.0"
}
mlflow.set_tags(tags)
标签用途 #
text
┌─────────────────────────────────────────────────────────────┐
│ 标签用途 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 分类和过滤: │
│ ├── 按团队筛选实验 │
│ ├── 按项目分组 │
│ └── 按优先级排序 │
│ │
│ 元数据记录: │
│ ├── 数据集版本 │
│ ├── 模型类型 │
│ └── 实验目的 │
│ │
│ 团队协作: │
│ ├── 负责人信息 │
│ ├── 审核状态 │
│ └── 备注说明 │
│ │
└─────────────────────────────────────────────────────────────┘
实验组织 #
实验命名规范 #
python
import mlflow
mlflow.set_experiment("customer-churn/prediction/v1")
mlflow.set_experiment("image-classification/resnet/experiment-1")
mlflow.set_experiment("nlp/sentiment-analysis/production")
实验层级结构 #
text
项目层级结构:
├── customer-churn/
│ ├── baseline/
│ ├── feature-engineering/
│ └── hyperparameter-tuning/
│
├── image-classification/
│ ├── resnet/
│ ├── vgg/
│ └── efficientnet/
│
└── nlp/
├── sentiment-analysis/
└── text-classification/
搜索实验 #
python
import mlflow
experiments = mlflow.search_experiments(
filter_string="tags.project = 'customer-churn'"
)
for exp in experiments:
print(f"Name: {exp.name}")
print(f"Tags: {exp.tags}")
运行查询 #
搜索运行 #
python
import mlflow
runs = mlflow.search_runs(
experiment_ids=["1", "2"],
filter_string="metrics.accuracy > 0.9 AND params.model_type = 'RandomForest'",
order_by=["metrics.accuracy DESC"],
max_results=100
)
print(runs[["run_id", "metrics.accuracy", "params.model_type"]])
搜索语法 #
text
┌─────────────────────────────────────────────────────────────┐
│ 搜索语法 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 参数过滤: │
│ params.key = 'value' │
│ params.key != 'value' │
│ │
│ 指标过滤: │
│ metrics.key > 0.9 │
│ metrics.key >= 0.9 │
│ metrics.key < 0.1 │
│ metrics.key <= 0.1 │
│ │
│ 标签过滤: │
│ tags.key = 'value' │
│ tags.key != 'value' │
│ │
│ 组合条件: │
│ condition1 AND condition2 │
│ condition1 OR condition2 │
│ │
│ 示例: │
│ metrics.accuracy > 0.9 AND params.model = 'rf' │
│ tags.team = 'ml' OR tags.team = 'ds' │
│ │
└─────────────────────────────────────────────────────────────┘
获取运行详情 #
python
import mlflow
run = mlflow.get_run("run_id")
print(f"Status: {run.info.status}")
print(f"Start Time: {run.info.start_time}")
print(f"Parameters: {run.data.params}")
print(f"Metrics: {run.data.metrics}")
print(f"Tags: {run.data.tags}")
列出运行工件 #
python
import mlflow
client = mlflow.tracking.MlflowClient()
artifacts = client.list_artifacts("run_id")
for artifact in artifacts:
print(f"Path: {artifact.path}")
print(f"Is Directory: {artifact.is_dir}")
嵌套运行 #
父子运行 #
python
import mlflow
with mlflow.start_run(run_name="parent-run") as parent_run:
mlflow.log_param("dataset", "iris")
for fold in range(5):
with mlflow.start_run(
run_name=f"fold-{fold}",
nested=True
) as child_run:
mlflow.log_metric("fold_accuracy", 0.95 - fold * 0.01)
mlflow.log_param("fold", fold)
使用场景 #
text
┌─────────────────────────────────────────────────────────────┐
│ 嵌套运行场景 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 交叉验证: │
│ ├── 父运行:整体实验 │
│ └── 子运行:每个 fold 的结果 │
│ │
│ 超参数搜索: │
│ ├── 父运行:搜索配置 │
│ └── 子运行:每组参数的结果 │
│ │
│ 集成学习: │
│ ├── 父运行:集成模型 │
│ └── 子运行:每个基学习器 │
│ │
│ 多阶段训练: │
│ ├── 父运行:完整训练流程 │
│ └── 子运行:每个训练阶段 │
│ │
└─────────────────────────────────────────────────────────────┘
自动记录 #
Scikit-learn 自动记录 #
python
import mlflow
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
mlflow.sklearn.autolog(
log_models=True,
log_datasets=True,
disable=False,
exclusive=False,
disable_for_unsupported_versions=False,
silent=False,
registered_model_name=None,
extra_tags=None
)
with mlflow.start_run():
model = RandomForestClassifier(n_estimators=100)
model.fit(X_train, y_train)
TensorFlow 自动记录 #
python
import mlflow
import tensorflow as tf
mlflow.tensorflow.autolog(
log_models=True,
log_datasets=True,
disable=False,
exclusive=False,
disable_for_unsupported_versions=False,
silent=False,
registered_model_name=None,
every_n_iter=1
)
with mlflow.start_run():
model.fit(X_train, y_train, epochs=10)
PyTorch Lightning 自动记录 #
python
import mlflow
import pytorch_lightning as pl
mlflow.pytorch.autolog(
log_models=True,
disable=False,
exclusive=False,
silent=False,
registered_model_name=None
)
trainer = pl.Trainer(max_epochs=10)
trainer.fit(model)
系统指标记录 #
启用系统指标 #
python
import mlflow
mlflow.enable_system_metrics_logging()
with mlflow.start_run():
pass
自定义系统指标 #
python
import mlflow
import psutil
import time
with mlflow.start_run():
for i in range(100):
cpu_percent = psutil.cpu_percent()
memory_percent = psutil.virtual_memory().percent
mlflow.log_metric("system/cpu_percent", cpu_percent, step=i)
mlflow.log_metric("system/memory_percent", memory_percent, step=i)
time.sleep(1)
最佳实践 #
1. 实验命名 #
python
import mlflow
mlflow.set_experiment(f"{project}/{task}/{version}")
2. 完整记录 #
python
import mlflow
with mlflow.start_run():
mlflow.log_params(params)
mlflow.log_metrics(metrics)
mlflow.sklearn.log_model(model, "model")
mlflow.log_artifact("config.yaml")
mlflow.set_tags(tags)
3. 异常处理 #
python
import mlflow
with mlflow.start_run() as run:
try:
train_model()
mlflow.log_metric("status", 1)
except Exception as e:
mlflow.set_tag("error", str(e))
mlflow.log_metric("status", 0)
raise
4. 条件记录 #
python
import mlflow
with mlflow.start_run():
if mlflow.active_run():
mlflow.log_metric("accuracy", accuracy)
下一步 #
现在你已经掌握了 MLflow Tracking 的核心功能,接下来学习 模型管理,了解如何管理和部署模型!
最后更新:2026-04-04