项目打包 #
MLflow Projects 概述 #
MLflow Projects 提供了一种打包数据科学代码的标准格式,使其可以在任何平台上可复现地运行。
text
┌─────────────────────────────────────────────────────────────┐
│ MLflow Projects 架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 项目代码 │ │
│ │ ├── train.py │ │
│ │ ├── preprocess.py │ │
│ │ └── utils.py │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ MLproject 文件 │ │
│ │ ├── 项目名称 │ │
│ │ ├── 环境配置 │ │
│ │ └── 入口点定义 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 运行环境 │ │
│ │ ├── Conda 环境 │ │
│ │ ├── Docker 容器 │ │
│ │ └── 系统环境 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
项目结构 #
基本项目结构 #
text
my_project/
├── MLproject # 项目描述文件
├── conda.yaml # Conda 环境配置
├── requirements.txt # Python 依赖
├── train.py # 训练脚本
├── preprocess.py # 预处理脚本
├── config/ # 配置文件
│ └── config.yaml
└── data/ # 数据目录
└── sample.csv
MLproject 文件 #
yaml
name: my_project
conda_env: conda.yaml
docker_env:
image: python:3.10-slim
entry_points:
main:
parameters:
data_path: {type: str, default: "data/train.csv"}
learning_rate: {type: float, default: 0.01}
epochs: {type: int, default: 100}
command: "python train.py --data_path {data_path} --lr {learning_rate} --epochs {epochs}"
preprocess:
parameters:
input_path: {type: str}
output_path: {type: str}
command: "python preprocess.py --input {input_path} --output {output_path}"
MLproject 文件详解 #
项目名称 #
yaml
name: customer-churn-prediction
环境配置 #
text
┌─────────────────────────────────────────────────────────────┐
│ 环境配置类型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. Conda 环境 │
│ ───────────────────────────────────────────────────── │
│ conda_env: conda.yaml │
│ 或 │
│ conda_env: │
│ name: mlflow-env │
│ channels: [conda-forge] │
│ dependencies: │
│ - python=3.10 │
│ - numpy │
│ - pandas │
│ │
│ 2. Docker 环境 │
│ ───────────────────────────────────────────────────── │
│ docker_env: │
│ image: python:3.10-slim │
│ volumes: ["/host/path:/container/path"] │
│ environment: │
│ - CUDA_VISIBLE_DEVICES=0 │
│ │
│ 3. 系统环境 │
│ ───────────────────────────────────────────────────── │
│ 不指定环境配置,使用当前系统环境 │
│ │
└─────────────────────────────────────────────────────────────┘
入口点定义 #
yaml
entry_points:
train:
parameters:
data_path: {type: str, default: "data/train.csv"}
learning_rate: {type: float, default: 0.01}
epochs: {type: int, default: 100}
batch_size: {type: int, default: 32}
command: "python train.py --data {data_path} --lr {learning_rate} --epochs {epochs} --batch_size {batch_size}"
evaluate:
parameters:
model_path: {type: str}
test_data: {type: str}
command: "python evaluate.py --model {model_path} --test {test_data}"
predict:
parameters:
model_path: {type: str}
input_data: {type: str}
output_path: {type: str, default: "predictions.csv"}
command: "python predict.py --model {model_path} --input {input_data} --output {output_path}"
参数类型 #
参数定义 #
yaml
parameters:
string_param: {type: str, default: "hello"}
int_param: {type: int, default: 100}
float_param: {type: float, default: 0.01}
bool_param: {type: bool, default: true}
required_param: {type: str}
参数类型说明 #
text
┌─────────────────────────────────────────────────────────────┐
│ 参数类型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ str (字符串) │
│ ───────────────────────────────────────────────────────── │
│ {type: str, default: "value"} │
│ 用于文件路径、模型名称等 │
│ │
│ int (整数) │
│ ───────────────────────────────────────────────────────── │
│ {type: int, default: 100} │
│ 用于 epochs, batch_size 等 │
│ │
│ float (浮点数) │
│ ───────────────────────────────────────────────────────── │
│ {type: float, default: 0.01} │
│ 用于 learning_rate, dropout 等 │
│ │
│ bool (布尔值) │
│ ───────────────────────────────────────────────────────── │
│ {type: bool, default: true} │
│ 用于开关选项 │
│ │
│ 必需参数(无默认值) │
│ ───────────────────────────────────────────────────────── │
│ {type: str} │
│ 运行时必须提供 │
│ │
└─────────────────────────────────────────────────────────────┘
运行项目 #
使用 mlflow run 命令 #
bash
mlflow run . -P learning_rate=0.01 -P epochs=100
mlflow run . -e train -P data_path=data/train.csv
mlflow run https://github.com/user/mlflow-project.git -P param=value
mlflow run . -e main -P param1=value1 -P param2=value2
使用 Python API #
python
import mlflow
mlflow.run(
uri=".",
entry_point="train",
parameters={
"learning_rate": 0.01,
"epochs": 100
}
)
mlflow.run(
uri="https://github.com/user/mlflow-project.git",
entry_point="main",
version="main",
parameters={
"data_path": "data/train.csv"
}
)
运行参数 #
text
┌─────────────────────────────────────────────────────────────┐
│ mlflow run 参数 │
├─────────────────────────────────────────────────────────────┤
│ │
│ -P, --parameter 设置参数 │
│ ───────────────────────────────────────────────────────── │
│ -P learning_rate=0.01 │
│ -P epochs=100 │
│ │
│ -e, --entry-point 指定入口点 │
│ ───────────────────────────────────────────────────────── │
│ -e train │
│ -e evaluate │
│ │
│ -v, --version 指定版本 │
│ ───────────────────────────────────────────────────────── │
│ -v v1.0 │
│ -v main │
│ │
│ --experiment-name 指定实验名称 │
│ ───────────────────────────────────────────────────────── │
│ --experiment-name my-experiment │
│ │
│ --backend-store-uri 指定存储后端 │
│ ───────────────────────────────────────────────────────── │
│ --backend-store-uri sqlite:///mlflow.db │
│ │
└─────────────────────────────────────────────────────────────┘
环境配置 #
Conda 环境 #
yaml
name: mlflow-project
channels:
- conda-forge
- defaults
dependencies:
- python=3.10
- numpy=1.24
- pandas=2.0
- scikit-learn=1.3
- pip
- pip:
- mlflow==2.10.0
- torch==2.0.0
Docker 环境 #
yaml
docker_env:
image: pytorch/pytorch:2.0.0-cuda11.7-cudnn8-runtime
volumes:
- "/host/data:/workspace/data"
- "/host/models:/workspace/models"
environment:
- CUDA_VISIBLE_DEVICES=0
- PYTHONPATH=/workspace/src
Dockerfile 示例 #
dockerfile
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
ENTRYPOINT ["python", "train.py"]
完整项目示例 #
项目结构 #
text
customer_churn/
├── MLproject
├── conda.yaml
├── requirements.txt
├── src/
│ ├── __init__.py
│ ├── train.py
│ ├── evaluate.py
│ ├── predict.py
│ └── utils.py
├── config/
│ └── config.yaml
├── data/
│ └── .gitkeep
└── README.md
MLproject 文件 #
yaml
name: customer-churn-prediction
conda_env: conda.yaml
entry_points:
train:
parameters:
data_path: {type: str, default: "data/train.csv"}
model_type: {type: str, default: "random_forest"}
n_estimators: {type: int, default: 100}
max_depth: {type: int, default: 10}
test_size: {type: float, default: 0.2}
command: >
python src/train.py
--data_path {data_path}
--model_type {model_type}
--n_estimators {n_estimators}
--max_depth {max_depth}
--test_size {test_size}
evaluate:
parameters:
model_path: {type: str}
test_data: {type: str}
command: >
python src/evaluate.py
--model_path {model_path}
--test_data {test_data}
predict:
parameters:
model_path: {type: str}
input_data: {type: str}
output_path: {type: str, default: "predictions.csv"}
command: >
python src/predict.py
--model_path {model_path}
--input_data {input_data}
--output_path {output_path}
conda.yaml 文件 #
yaml
name: customer-churn
channels:
- conda-forge
- defaults
dependencies:
- python=3.10
- numpy=1.24
- pandas=2.0
- scikit-learn=1.3
- matplotlib=3.7
- seaborn=0.12
- pyyaml=6.0
- pip
- pip:
- mlflow==2.10.0
- xgboost==2.0.0
- lightgbm==4.0.0
train.py 示例 #
python
import argparse
import pandas as pd
import mlflow
import mlflow.sklearn
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument("--data_path", type=str, default="data/train.csv")
parser.add_argument("--model_type", type=str, default="random_forest")
parser.add_argument("--n_estimators", type=int, default=100)
parser.add_argument("--max_depth", type=int, default=10)
parser.add_argument("--test_size", type=float, default=0.2)
return parser.parse_args()
def main():
args = parse_args()
data = pd.read_csv(args.data_path)
X = data.drop("target", axis=1)
y = data["target"]
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=args.test_size, random_state=42
)
mlflow.set_experiment("customer-churn")
with mlflow.start_run():
mlflow.log_params({
"model_type": args.model_type,
"n_estimators": args.n_estimators,
"max_depth": args.max_depth,
"test_size": args.test_size
})
model = RandomForestClassifier(
n_estimators=args.n_estimators,
max_depth=args.max_depth,
random_state=42
)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
metrics = {
"accuracy": accuracy_score(y_test, y_pred),
"precision": precision_score(y_test, y_pred),
"recall": recall_score(y_test, y_pred),
"f1_score": f1_score(y_test, y_pred)
}
mlflow.log_metrics(metrics)
mlflow.sklearn.log_model(model, "model")
print(f"Accuracy: {metrics['accuracy']:.4f}")
print(f"F1 Score: {metrics['f1_score']:.4f}")
if __name__ == "__main__":
main()
运行远程项目 #
从 Git 仓库运行 #
bash
mlflow run https://github.com/user/mlflow-project.git \
-e train \
-P data_path=s3://bucket/data/train.csv \
-P learning_rate=0.01
从特定分支运行 #
bash
mlflow run https://github.com/user/mlflow-project.git \
-v feature-branch \
-e train \
-P param=value
从特定标签运行 #
bash
mlflow run https://github.com/user/mlflow-project.git \
-v v1.0.0 \
-e train
工作流编排 #
多步骤工作流 #
python
import mlflow
with mlflow.start_run() as parent_run:
preprocess_run = mlflow.run(
".",
entry_point="preprocess",
parameters={
"input_path": "data/raw.csv",
"output_path": "data/processed.csv"
}
)
train_run = mlflow.run(
".",
entry_point="train",
parameters={
"data_path": "data/processed.csv",
"learning_rate": 0.01
}
)
evaluate_run = mlflow.run(
".",
entry_point="evaluate",
parameters={
"model_path": train_run.run_id,
"test_data": "data/test.csv"
}
)
使用 Databricks Jobs #
python
import mlflow
mlflow.run(
"databricks://my-workspace/my-project",
entry_point="train",
parameters={"param": "value"},
backend="databricks"
)
最佳实践 #
1. 项目结构规范 #
text
project/
├── MLproject # 必需
├── conda.yaml # 推荐
├── requirements.txt # 可选
├── src/ # 源代码
├── config/ # 配置文件
├── tests/ # 测试代码
├── data/ # 数据目录
└── README.md # 文档
2. 参数命名规范 #
yaml
parameters:
data_path: {type: str, default: "data/train.csv"}
model.learning_rate: {type: float, default: 0.01}
model.batch_size: {type: int, default: 32}
train.epochs: {type: int, default: 100}
3. 环境隔离 #
yaml
conda_env:
name: project-env-v1
channels: [conda-forge]
dependencies:
- python=3.10
- pip
- pip:
- mlflow
- scikit-learn
4. 版本控制 #
bash
git tag v1.0.0
git push origin v1.0.0
mlflow run https://github.com/user/project.git -v v1.0.0
下一步 #
现在你已经掌握了 MLflow Projects 的核心功能,接下来学习 模型注册中心,了解如何管理模型版本和生命周期!
最后更新:2026-04-04