{T}

MLOps:机器学习模型交付

背景与问题定义

机器学习模型的交付与传统软件交付存在本质差异。传统软件的交付对象是代码,代码的行为由逻辑确定;而 ML 模型的交付对象是"代码 + 数据 + 模型",模型的行为由数据分布决定。当数据分布发生变化(数据漂移),模型性能将不可预测地退化,必须重新训练和部署。此外,ML 实验的不可复现性、训练与推理环境的差异、模型版本与数据版本的关联等问题,使得传统 CI/CD 流水线无法直接覆盖 ML 交付全流程。

MLOps(Machine Learning Operations)正是为解决这些问题而生的实践体系。它将 DevOps 的理念扩展到 ML 领域,实现模型从实验、训练、评估到部署、监控、再训练的端到端自动化。

核心问题:如何将 ML 模型从实验阶段安全、可复现、可持续地交付到生产环境,并应对数据漂移等 ML 特有的挑战?

核心概念

MLOps 与传统持续交付的差异

维度传统持续交付MLOps
交付对象代码代码 + 数据 + 模型
行为决定因素代码逻辑数据分布 + 模型权重
质量度量测试通过率、代码覆盖率模型精度、F1 Score、AUC
退化原因代码 Bug数据漂移(Data Drift)、概念漂移(Concept Drift)
回滚方式代码回滚模型回滚 + 数据回滚
测试方法单元/集成/E2E 测试模型评估、A/B 测试、影子部署
环境一致性构建环境 → 生产环境训练环境 → 推理环境(GPU 差异)
版本管理Git(代码版本)Git + DVC(数据版本)+ Model Registry(模型版本)

MLOps 成熟度模型

图表渲染中…

持续训练(Continuous Training)

CT 是 MLOps 独有的概念——当检测到数据漂移或性能退化时,自动触发模型重新训练:

触发方式场景实现方法
定时触发定期更新模型(如每日/每周)Cron / Airflow / Kubeflow Pipeline
数据漂移触发数据分布显著变化监控统计指标(PSI、KL 散度)
性能退化触发模型精度低于阈值监控模型评估指标
人工触发业务需求变化手动启动 Pipeline

架构设计

MLOps 端到端架构

图表渲染中…

LLMOps 架构

大语言模型(LLM)的交付引入了新的挑战,LLMOps 在 MLOps 基础上增加了 Prompt 管理、RAG Pipeline 和 Token 成本追踪:

图表渲染中…

实现方案

工具链选型

环节推荐工具备选说明
实验追踪MLflowWeights & Biases, Comet MLMLflow 开源且功能全面
数据版本化DVCLakeFS, Delta LakeDVC 与 Git 集成,轻量级
ML PipelineKubeflow PipelinesAirflow, Prefect, DagsterKubeflow 原生 K8s
模型注册MLflow Model RegistryVertex AI, SageMaker与实验追踪统一
模型服务KServe / BentoMLTensorFlow Serving, TritonKServe 是 K8s 原生
特征存储FeastTecton, HopsworksFeast 开源
数据验证Great ExpectationsPandera, SodaGreat Expectations 功能最全面
漂移检测Evidently AINannyML, Alibi DetectEvidently 开源且可视化

MLflow 实验追踪配置

python
# MLflow 实验追踪示例
import mlflow
import mlflow.sklearn
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score
 
# 设置 MLflow Tracking Server
mlflow.set_tracking_uri("http://mlflow.example.com:5000")
mlflow.set_experiment("orders-delay-prediction")
 
# 定义可复现的训练过程
def train_model(X_train, y_train, X_test, y_test, params):
    with mlflow.start_run(run_name=f"rf-{params['n_estimators']}") as run:
        # 记录参数
        mlflow.log_params(params)
 
        # 训练模型
        model = RandomForestClassifier(
            n_estimators=params["n_estimators"],
            max_depth=params["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),
            "f1_score": f1_score(y_test, y_pred, average="weighted"),
            "precision": precision_score(y_test, y_pred, average="weighted"),
            "recall": recall_score(y_test, y_pred, average="weighted")
        }
        mlflow.log_metrics(metrics)
 
        # 记录模型
        mlflow.sklearn.log_model(
            model,
            "model",
            registered_model_name="orders-delay-prediction"
        )
 
        # 记录数据版本
        mlflow.log_param("data_version", params.get("data_version", "unknown"))
 
        return run.info.run_id, metrics
 
# 执行训练
params = {
    "n_estimators": 100,
    "max_depth": 10,
    "data_version": "dvc://datasets/orders/v3"
}
run_id, metrics = train_model(X_train, y_train, X_test, y_test, params)
print(f"Run ID: {run_id}, Metrics: {metrics}")

Kubeflow Pipeline 定义示例

python
# Kubeflow Pipeline 定义
from kfp import dsl
from kfp.dsl import component, Output, Model, Metrics
 
@component(base_image="python:3.11")
def data_ingestion(data_path: str, output_data: Output[dsl.Dataset]):
    import pandas as pd
    df = pd.read_csv(data_path)
    df.to_csv(output_data.path, index=False)
 
@component(base_image="python:3.11")
def data_validation(input_data: dsl.Dataset, validation_result: Output[Metrics]):
    import pandas as pd
    df = pd.read_csv(input_data.path)
    # 数据质量检查
    null_ratio = df.isnull().sum().sum() / (df.shape[0] * df.shape[1])
    validation_result.log_metric("null_ratio", null_ratio)
    validation_result.log_metric("row_count", len(df))
    validation_result.log_metric("column_count", len(df.columns))
 
@component(base_image="python:3.11")
def train_model(
    input_data: dsl.Dataset,
    n_estimators: int,
    output_model: Output[Model],
    output_metrics: Output[Metrics]
):
    import pandas as pd
    import pickle
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.model_selection import train_test_split
    from sklearn.metrics import accuracy_score, f1_score
 
    df = pd.read_csv(input_data.path)
    X = df.drop("target", axis=1)
    y = df["target"]
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
 
    model = RandomForestClassifier(n_estimators=n_estimators, random_state=42)
    model.fit(X_train, y_train)
 
    y_pred = model.predict(X_test)
    output_metrics.log_metric("accuracy", accuracy_score(y_test, y_pred))
    output_metrics.log_metric("f1_score", f1_score(y_test, y_pred, average="weighted"))
 
    with open(output_model.path, "wb") as f:
        pickle.dump(model, f)
 
@dsl.pipeline(name="ml-training-pipeline")
def training_pipeline(
    data_path: str = "gs://ml-data/orders/v3/train.csv",
    n_estimators: int = 100
):
    ingest = data_ingestion(data_path=data_path)
    validate = data_validation(input_data=ingest.outputs["output_data"])
    train = train_model(
        input_data=ingest.outputs["output_data"],
        n_estimators=n_estimators
    )
    # 数据验证失败则跳过训练
    train.after(validate)

分步实施指南

第一阶段:实验规范化(Month 1-2)

  1. 部署 MLflow Tracking Server
  2. 将所有 Notebook 实验迁移到 MLflow 追踪
  3. 建立实验命名规范和标签体系
  4. 引入 DVC 管理数据版本

第二阶段:Pipeline 编排(Month 3-4)

  1. 将训练流程封装为 Kubeflow Pipeline
  2. 实现数据摄取 → 验证 → 特征计算 → 训练 → 评估的自动化流水线
  3. 建立模型注册中心(Model Registry)
  4. 引入模型评估门禁(精度低于阈值则阻止部署)

第三阶段:自动化部署(Month 5-6)

  1. 使用 KServe / BentoML 部署模型推理服务
  2. 实现模型 A/B 测试和影子部署
  3. 建立模型性能监控(推理延迟、精度退化)
  4. 引入漂移检测(Evidently AI)

第四阶段:持续训练(Month 7+)

  1. 实现漂移检测触发自动再训练
  2. 建立模型版本与数据版本的关联
  3. 引入 LLMOps 实践(Prompt 版本管理、RAG Pipeline)
  4. 建立模型成本追踪(Token 用量、GPU 消耗)

最佳实践

业界推荐做法

  1. 版本一切:代码(Git)、数据(DVC)、模型(Model Registry)、Prompt(版本控制)——ML 交付的不可复现性问题源于缺乏版本管理
  2. 实验追踪先行:在建立 Pipeline 之前先实现实验追踪(MLflow),否则无法复现任何实验结果
  3. 评估门禁:模型部署前必须通过自动化评估——精度低于阈值或延迟超过阈值则阻止部署
  4. 影子部署:新模型先以影子模式运行(接收流量但不返回结果),对比与旧模型的输出差异
  5. 漂移检测 + CT:监控数据漂移和性能退化,自动触发再训练——这是 ML 系统与软件系统的本质区别

常见反模式与规避方法

反模式表现危害规避方法
Notebook 即生产直接在 Jupyter Notebook 中运行推理不可扩展、不可复现Pipeline 化 + 模型服务化
不追踪实验模型训练不记录参数和指标无法复现、无法对比MLflow 实验追踪
不验证数据训练前不检查数据质量垃圾进垃圾出Great Expectations 数据验证
忽视漂移部署后不监控数据分布变化模型逐渐失效Evidently AI 漂移检测
模型无版本部署时直接覆盖旧模型无法回滚Model Registry + 模型版本化

效果度量

MLOps 成熟度指标

指标Level 0Level 1Level 2Level 3
实验可复现率< 10%> 70%> 90%> 95%
模型部署自动化率0%30%80%95%
数据版本覆盖率0%> 50%> 80%> 95%
漂移检测延迟天级小时级分钟级
模型上线时间小时分钟

ML 系统质量指标

指标定义目标
模型精度在生产数据上的评估指标(AUC/F1/MAE)≥ 离线评估的 95%
推理延迟 P99模型推理的 P99 响应时间< 业务 SLA
数据漂移率PSI > 阈值的数据特征比例< 10%
模型退化时间从部署到精度低于阈值的时间> 30 天
再训练成功率自动再训练 Pipeline 成功运行的比例> 90%

总结

核心要点

  1. MLOps 将 DevOps 理念扩展到 ML 领域,核心差异在于交付对象是"代码 + 数据 + 模型",行为由数据分布决定
  2. 持续训练(CT)是 MLOps 独有的概念——漂移检测触发自动再训练
  3. 版本一切(代码、数据、模型、Prompt)是解决 ML 不可复现性的基础
  4. MLflow 是实验追踪和模型注册的事实标准,Kubeflow 是 ML Pipeline 编排的首选
  5. LLMOps 在 MLOps 基础上增加了 Prompt 管理、RAG Pipeline 和 Token 成本追踪

延伸阅读