登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  科技周边 >  人工智能

MLflow 怎样记录模型版本和评估指标

来源:17golang原创

时间:2026-10-29 02:07:32 313浏览 收藏

当模型从一次训练走向多次迭代时,最容易混在一起的是三件事:这次训练用了什么参数、生成了哪个模型版本、测试集表现到底怎样。MLflow 的做法是把它们放进同一条可追踪链路:Run 保存参数和指标,模型注册表保存同名模型的版本,评估 API 再把测试集结果和评估产物写回运行记录。

官方地址:https://mlflow.org/

最小可靠方案是先用 mlflow.log_params、mlflow.log_metrics 和模型 flavor 的 log_model 保存一次 Run,再通过 registered_model_name 注册版本,最后用 mlflow.models.evaluate 对测试集评估。这样查模型版本时不会丢掉它对应的实验参数与评估上下文。

本文使用分类模型举例,代码只展示记录关系,不要求在本文环境中运行。

先把实验、Run 和注册模型名分开

MLflow 中,Experiment 是一组运行记录的容器,Run 是一次训练或评估过程,Registered Model 则是面向生命周期管理的模型名称。模型注册后,同一个名称下会产生 version 1、version 2 等版本;因此不要把 Run ID 直接当成模型版本。

先固定 Tracking URI 和实验名,再决定一个不会随着日期变化的注册模型名。例如线上模型统一叫 fraud-risk-classifier,训练批次、数据集版本和提交号放在参数或标签中。这样后续搜索时能按实验、Run、模型版本三个维度交叉定位。

在同一个 Run 里记录参数、指标和模型

训练参数回答“怎么训练”,手工指标回答“训练时观察到什么”,模型制品回答“最终保存了什么”。三者放在同一个 start_run 上下文中,后续从 Run 反查模型时才有完整上下文。

import mlflow
import mlflow.sklearn
from mlflow.models import infer_signature

# 连接到 Tracking Server;本地文件存储也可以替换为服务端地址
mlflow.set_tracking_uri("http://localhost:5000")
mlflow.set_experiment("fraud-risk-training")

# 假设 model、X_test、y_test 已由上游训练流程准备好
with mlflow.start_run(run_name="random-forest-baseline") as run:
    # 记录会影响复现和比较的训练参数
    mlflow.log_params({
        "model_type": "RandomForestClassifier",
        "n_estimators": 200,
        "random_state": 42,
    })

    # 记录训练阶段已经计算出的指标,数值必须是可记录的标量
    accuracy = float((model.predict(X_test) == y_test).mean())
    mlflow.log_metrics({"test_accuracy_manual": accuracy})
    mlflow.set_tags({"dataset_version": "v2026-10", "stage": "candidate"})

    # signature 说明输入输出形状;注册模型名决定版本归属
    signature = infer_signature(X_test, model.predict(X_test))
    model_info = mlflow.sklearn.log_model(
        model,
        name="model",
        signature=signature,
        registered_model_name="fraud-risk-classifier",
    )

    # 保留 Run ID,便于把模型版本与本次实验记录关联起来
    print(run.info.run_id, model_info.model_uri)

这里的关键不是指标名称,而是指标必须与测试集、数据版本和 Run 同时可解释。registered_model_name 负责把模型放入注册表;如果只调用 log_model 而不注册,仍然可以从 artifact URI 加载,但不会自动得到注册模型版本。

MLflow Run、模型参数、手工指标、模型制品与注册模型版本的静态关系说明图
图1:结构说明图,查看 Run 如何连接参数、指标、模型制品和注册模型版本;这是原创静态说明图,不是运行截图。

用 registered_model_name 形成可读取的模型版本

当相同注册模型名再次接收新的模型制品时,MLflow 会为它生成新的版本。写作时不要把具体版本号硬编码进训练脚本,可以在发布决策阶段读取注册表返回的版本或使用别名管理指向关系。

import mlflow

# 版本号是注册表产生的结果,不要在代码里假定永远是 1
model_uri = "models:/fraud-risk-classifier/2"

# 通过模型名和版本读取注册表中的模型制品
loaded_model = mlflow.sklearn.load_model(model_uri)
predictions = loaded_model.predict(X_test)

# 只有在确认对应测试集与发布条件后,才把版本推进到下一阶段
print(f"loaded predictions: {len(predictions)}")

models:/模型名/版本号 是稳定的读取方式之一。需要注意,模型版本说明“注册表中的哪一版”,而 Run 的参数、标签和评估结果说明“它为什么是这一版”;两类信息不能互相替代。

用 mlflow.models.evaluate 记录评估指标

手工记录一个 accuracy 适合保存训练流程已有的数值,但模型评估还需要统一的输入、目标列和任务类型。对分类任务,可以把测试集复制成包含标签列的 DataFrame,再把已记录模型的 URI 交给 mlflow.models.evaluate。

import mlflow

# eval_data 至少包含模型输入列和目标列 label
eval_data = X_test.copy()
eval_data["label"] = y_test

with mlflow.start_run(run_name="evaluate-registered-v2"):
    # 由注册版本反查模型,避免评估了另一份未注册文件
    result = mlflow.models.evaluate(
        "models:/fraud-risk-classifier/2",
        eval_data,
        targets="label",
        model_type="classifier",
    )

    # 指标来自评估结果对象,按名称读取并再次写入摘要指标
    mlflow.log_metrics({
        "eval_accuracy": float(result.metrics["accuracy_score"]),
        "eval_f1": float(result.metrics["f1_score"]),
    })
    print(result.metrics)
    print(result.artifacts)

经典机器学习评估会返回指标、图表和评估表等结果。分类任务常见的 accuracy、precision、recall、F1 和 ROC-AUC 不能只挑一个看:类别不均衡时,accuracy 可能掩盖少数类识别能力;具体采用哪些指标,应由业务目标决定。

MLflow 评估结果、accuracy、F1、ROC-AUC、评估表与模型版本的静态关系说明图
图2:结构说明图,展示评估结果如何把指标、评估表和图表关联到已注册模型版本;这是原创静态说明图,不是运行证据。

按三层信息判断模型是否值得推进

落地时可以用三个问题收尾:

  • 参数层:这次 Run 的训练参数、数据集标签和代码版本是否能解释差异?
  • 版本层:评估的 URI 是否确实指向要比较的注册模型版本,而不是临时 artifact?
  • 指标层:测试集的 accuracy、F1、ROC-AUC 或回归误差,是否满足当前业务阈值?

如果只记录指标、不保存模型 URI,无法确认分数对应哪份模型;如果只注册模型、不保留评估结果,又无法解释为什么推进这一版。MLflow 的价值正在于把 Run、版本和评估产物放到同一条可回溯链上。

常见问题

只调用 log_model 会自动生成模型版本吗?

不会。它会保存模型制品;要进入 Model Registry,需要使用 registered_model_name 或另行调用注册 API。

mlflow.models.evaluate 和手工 log_metric 有什么区别?

log_metric 只保存你传入的标量;evaluate 还负责按任务类型计算一组指标并生成评估产物。两者可以并用,但不要把同一个指标的来源混写。

评估结果应该写到训练 Run 还是单独 Run?

小流程可以写在训练 Run 中;如果一个注册版本要被多套数据集重复评估,单独建立评估 Run 更清楚,并在标签中记录被评估的模型 URI 和数据集版本。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>