目标:建立一个可复现、可审计、可自动化的 ML 生命周期(数据版本、训练、模型注册、CI/CD、容器部署)。
栈:Git + DVC(数据版本)+ MLflow(实验 & 模型追踪)+ Docker + GitHub Actions(CI)+ MinIO(对象存储,替代 S3)。
一、适用场景与优势
适合以下场景:
- 团队化 ML 开发,需要追踪实验与数据版本;
- 希望把模型训练纳入 CI 流程,自动化测试与部署;
- 想要保证“代码 + 数据 + 环境”可复现。
优势:
- 数据与模型有版本控制(DVC + Git);
- 实验追踪与模型注册(MLflow);
- 自动化训练与部署(GitHub Actions + Docker);
- 可在本地、云或私有 infra 上复现。
二、准备环境
本地或服务器准备:
- Git
- Python 3.9+
- Docker & Docker Compose
- GitHub 仓库(Public/Private)
- MinIO(或 S3)作为远程存储(DVC 数据与 MLflow artifact 存储)
- 推荐使用 venv 或 Conda 管理虚拟环境
示例安装(Ubuntu):
sudo apt update
sudo apt install -y git docker.io docker-compose
python3 -m venv .venv && source .venv/bin/activate
pip install –upgrade pip
pip install dvc[all] mlflow boto3 sklearn pandas
三、项目结构(模板)
ml-pipeline/
├── data/ # 本地小样例数据(不要放大数据)
├── src/
│ ├── train.py
│ ├── features.py
│ └── model.py
├── Dockerfile
├── docker-compose.yml
├── dvc.yaml # DVC pipeline
├── params.yaml # 可变参数
├── requirements.txt
├── .github/workflows/ci.yml # GitHub Actions
└── README.md
四、示例代码(最小可运行示例)
1)
src/features.py
负责读取数据并做简单特征处理。
# src/features.py
import pandas as pd
def load_data(path):
return pd.read_csv(path)
def preprocess(df):
# 简单示例:处理缺失值并返回 X,y
df = df.dropna()
X = df.drop(columns=[‘target’])
y = df[‘target’]
return X, y
2)
src/model.py
包含训练与保存模型逻辑(MLflow 集成)。
# src/model.py
import mlflow
import mlflow.sklearn
from sklearn.ensemble import RandomForestClassifier
def train(X, y, params):
model = RandomForestClassifier(n_estimators=params.get(“n_estimators”,100), random_state=42)
model.fit(X, y)
return model
def save_model(model, model_name=”model”):
mlflow.sklearn.log_model(model, artifact_path=model_name)
3)
src/train.py
训练脚本,负责读取参数、数据、执行训练并记录到 MLflow。
# src/train.py
import yaml
import mlflow
import argparse
from features import load_data, preprocess
from model import train, save_model
def main(params_path=”params.yaml”):
# 加载参数
params = {}
with open(params_path) as f:
params = yaml.safe_load(f)
data_path = params[‘data’][‘train_path’]
mlflow_uri = params[‘mlflow’].get(‘tracking_uri’, ‘http://localhost:5000’)
mlflow.set_tracking_uri(mlflow_uri)
with mlflow.start_run():
df = load_data(data_path)
X, y = preprocess(df)
model = train(X, y, params[‘model’])
save_model(model)
mlflow.log_params(params[‘model’])
if __name__ == “__main__”:
import sys
path = sys.argv[1] if len(sys.argv) > 1 else “params.yaml”
main(path)
4)
params.yaml
训练参数与路径。
data:
train_path: data/train.csv
model:
n_estimators: 100
mlflow:
tracking_uri: http://mlflow:5000
五、DVC:数据版本与 pipeline
初始化 DVC 与远程存储(MinIO)
- 初始化 Git、DVC:
git init
dvc init
git add .dvc .gitignore
git commit -m “init repo with dvc”
- 启动本地 MinIO(示例 docker-compose 可在后面),获取 endpoint/keys 。然后配置 DVC remote:
dvc remote add -d myremote s3://mlflow-dvc
dvc remote modify myremote endpointurl http://localhost:9000
dvc remote modify myremote access_keyid minioadmin
dvc remote modify myremote secret_access_key minioadmin
上面 -d 表明设置为默认 remote。
- 将训练数据添加到 DVC 追踪并推送到远程:
dvc add data/train.csv
git add data/train.csv.dvc .gitignore
git commit -m “add train data to dvc”
dvc push
DVC pipeline(
dvc.yaml
)
示例 pipeline:prepare -> train
stages:
prepare:
cmd: python src/features.py # 若有数据准备脚本
deps:
– src/features.py
– data/train.csv
outs:
– data/processed
train:
cmd: python src/train.py params.yaml
deps:
– src/train.py
– src/model.py
– src/features.py
– data/processed
params:
– model.n_estimators
outs:
– models/model.pkl
实际项目可把每步拆成更细粒度 stage。
六、MLflow:启动 Tracking Server 与 artifact 存储
我们将使用 MLflow Server 并将 artifact 存在 MinIO(对象存储)。
docker-compose 示例(包含 MinIO & MLflow)
version: ‘3.8’
services:
minio:
image: minio/minio
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
command: server /data
ports:
– “9000:9000”
mlflow:
image: mlflow/mlflow:2.5.0
environment:
MLFLOW_TRACKING_URI: http://0.0.0.0:5000
AWS_ACCESS_KEY_ID: minioadmin
AWS_SECRET_ACCESS_KEY: minioadmin
MLFLOW_S3_ENDPOINT_URL: http://minio:9000
ports:
– “5000:5000”
command: mlflow server –backend-store-uri sqlite:///mlflow.db –default-artifact-root s3://mlflow-artifacts
depends_on:
– minio
启动:
docker compose up -d
登录 MinIO 控制台 http://localhost:9000 创建 bucket mlflow-artifacts,并确保 MLflow 环境变量配置正确。
MLflow server 的 –default-artifact-root 指向 S3(MinIO),后续 mlflow.sklearn.log_model 会把模型上传到 MinIO。
七、容器化:Dockerfile 与运行
Dockerfile(用于训练环境)
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install –no-cache-dir -r requirements.txt
COPY . .
CMD [“python”, “src/train.py”, “params.yaml”]
构建镜像:
docker build -t ml-train:latest .
运行训练(在 docker compose 网络中,确保 mlflow 与 minio 可达):
docker run –env-file .env ml-train:latest
.env 包含 MLflow/MinIO 的访问配置。
八、CI:用 GitHub Actions 自动化训练并注册模型(示例)
.github/workflows/ci.yml:
name: ml-ci
on:
push:
branches:
– main
jobs:
dvc-push:
runs-on: ubuntu-latest
steps:
– uses: actions/checkout@v4
– name: Set up Python
uses: actions/setup-python@v4
with:
python-version: 3.9
– name: Install deps
run: |
pip install dvc[all] boto3
– name: Configure dvc remote (MinIO)
run: |
dvc remote modify myremote access_keyid ${{ secrets.MINIO_ACCESS }}
dvc remote modify myremote secret_access_key ${{ secrets.MINIO_SECRET }}
dvc remote modify myremote endpointurl ${{ secrets.MINIO_ENDPOINT }}
– name: Pull data
run: dvc pull -r myremote
train-and-log:
runs-on: ubuntu-latest
needs: dvc-push
services:
minio:
image: minio/minio
ports: [‘9000:9000’]
env:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
options: –entrypoint “sh -c ‘minio server /data & sleep 5′”
steps:
– uses: actions/checkout@v4
– name: Setup Python
uses: actions/setup-python@v4
with:
python-version: 3.9
– name: Install deps
run: pip install -r requirements.txt mlflow boto3
– name: Start mlflow server (simple)
run: |
pip install mlflow
nohup mlflow server –backend-store-uri sqlite:///mlflow.db –default-artifact-root s3://mlflow-artifacts –host 0.0.0.0 –port 5000 &
sleep 5
– name: Run training
env:
MLFLOW_TRACKING_URI: http://localhost:5000
AWS_ACCESS_KEY_ID: minioadmin
AWS_SECRET_ACCESS_KEY: minioadmin
AWS_REGION: us-east-1
MLFLOW_S3_ENDPOINT_URL: http://localhost:9000
run: |
python src/train.py params.yaml
注意:GitHub Actions 中使用 MinIO 仅为演示。生产环境提议使用托管 S3 /专门的 ML infra。
九、模型部署(Serving)
部署方式有几种:
- MLflow Model Serving(简易方法):
mlflow models serve -m “runs:/<run_id>/model” -p 1234 –no-conda
- 使用 Docker 打包模型推理服务(推荐用于生产):
- 写一个简单的 Flask/FastAPI 服务,加载 MLflow 模型 URI(mlflow.pyfunc.load_model),并提供 REST predict 接口。
- 构建镜像并推到私有 registry,然后用 Kubernetes/ ECS 等部署。
示例 serve.py(FastAPI):
from fastapi import FastAPI
import mlflow.pyfunc
import pandas as pd
app = FastAPI()
model = mlflow.pyfunc.load_model(“models:/my_registered_model/Production”)
@app.post(“/predict”)
def predict(payload: dict):
df = pd.DataFrame([payload])
preds = model.predict(df)
return {“pred”: preds.tolist()}
十、实用提议与常见陷阱
- 不要把大数据直接放 Git:使用 DVC + remote(MinIO/S3)。
- 参数化:把超参数放 params.yaml,并在 DVC/CI 中读取。
- 追踪环境:记录 pip freeze 或使用 conda 环境文件;思考用 Dockerfile 固化环境。
- 安全:把 MinIO/MLflow 凭证放在 CI secrets(如 GitHub Secrets)。
- 可复现:用 dvc repro 在任何机器复现 pipeline。
- 资源隔离:训练最好在 GPU 节点或云实例上运行(CI 仅用于 smoke test)。
- 模型注册:把生产模型放入 MLflow Model Registry 并标注版本(Staging/Production)。
十一、完整流程一键复现(简要命令清单)
# 克隆 repo
git clone <repo>
cd ml-pipeline
# 初始化虚拟环境
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
# 启动 MinIO + MLflow(docker compose)
docker compose up -d
# DVC 初始化并 push 数据(一次)
dvc init
dvc remote add -d myremote s3://mlflow-dvc
dvc remote modify myremote endpointurl http://localhost:9000
dvc remote modify myremote access_keyid minioadmin
dvc remote modify myremote secret_access_key minioadmin
dvc add data/train.csv
git add data/train.csv.dvc .gitignore
git commit -m “add data”
dvc push
# 运行训练(本地)
python src/train.py params.yaml
# 在 MLflow UI 查看实验: http://localhost:5000
十二、结语
本文展示了如何用 DVC + MLflow + Docker + GitHub Actions 搭建一个可复现、可自动化的 ML 生命周期。通过数据版本、实验追踪与 CI 流水线,你可以把机器学习工作流带进工程化、可审计的轨道。
若你希望,我可以把该示例整理成一个 GitHub 模板仓库(含 README、完整 docker-compose、K8s 清单与示例数据),并提供一键部署脚本。















暂无评论内容