MLflow models Python API 全解:Flavor 模型格式、签名、评估与部署
【免费下载链接】mlflowThe open source AI engineering platform for agents, LLMs, and ML models. MLflow enables teams of all sizes to debug, evaluate, monitor, and optimize production-quality AI applications while controlling costs and managing access to models and data.项目地址: https://gitcode.com/GitHub_Trending/ml/mlflow
MLflow 的mlflow.models模块是整个 MLflow 模型生命周期管理的中枢 API,它定义了"带 Flavor 的模型"这一核心抽象,并提供了模型记录(logging)、签名(signature)推断与校验、离线评估、无环境预测、Docker 镜像构建以及模型即代码(model as code)等一整套能力。本文基于当前仓库中 mlflow.models.rst 所挂接的 API 文档(Sphinx autodoc),结合 mlflow/models 目录下的真实源码实现,系统讲解该模块的每个公开类与方法,帮助你在训练脚本、CI 流水线和服务化部署中正确使用这些 API。
说明:
mlflow.models.rst是一份 Sphinx autodoc 占位文档,通过automodule指令把mlflow.models包内各成员(Model、ModelInfo、evaluate、infer_signature等)的 docstring 渲染成参考页。因此本文的内容骨架即这些 API 的官方语义,细节均对照源码核实。
模块定位:以 Flavor 为核心的模型抽象
mlflow.models模块的设计目标,正如其包 docstring 所写:提供一种以"Flavor"保存机器学习模型的 API,使模型能够被不同的下游工具理解。所谓 Flavor,就是同一份模型资产在不同生态下的"呈现方式"——例如同一个 sklearn 模型,可以同时被python_function(pyfunc 通用接口)、sklearn(原生 sklearn 加载方式)两种 Flavor 描述。
从 mlflow/models/init.py 可以看到,模块内置了以下 Flavor 子模块:
| Flavor 模块 | 适用框架 |
|---|---|
mlflow.catboost | CatBoost |
mlflow.dspy | DSPy |
mlflow.h2o | H2O |
mlflow.langchain | LangChain |
mlflow.lightgbm | LightGBM |
mlflow.llama_index | LlamaIndex |
mlflow.onnx | ONNX |
mlflow.openai | OpenAI |
mlflow.paddle | PaddlePaddle |
mlflow.pmdarima | pmdarima |
mlflow.prophet | Prophet |
mlflow.pyfunc | 任意 Python 可调用对象(通用) |
mlflow.pyspark.ml/mlflow.spark | PySpark / Spark |
mlflow.pytorch | PyTorch |
mlflow.sklearn | scikit-learn |
mlflow.spacy | spaCy |
mlflow.statsmodels | statsmodels |
mlflow.tensorflow | TensorFlow / Keras |
mlflow.transformers | Hugging Face Transformers |
mlflow.xgboost | XGBoost |
每个 Flavor 模块都实现了save_model/log_model/load_model三件套,其中log_model在仓库中统一收敛到Model.log()/Model._log_v2()这两个类方法(见 mlflow/models/model.py),完成"保存到临时目录 → 校验 serving input → 记录 artifacts → 关联 run → 注册 Model Registry"的完整链路。除此之外,__init__.py还向外部导出了evaluate、make_metric、ModelSignature、infer_signature、predict、build_docker、set_model、ModelConfig、Resource等一批顶层 API,本文后续逐一展开。
Model 与 ModelInfo:模型元数据的一体两面
Model类:MLmodel 文件的面向对象表示
Model(mlflow/models/model.py)是"一个可以支持多种 Flavor 的 MLflow 模型",本质上是模型目录下MLmodelYAML 文件的编程式抽象。其构造参数与MLmodel文件字段一一对应:
| 字段 | 含义 | 备注 |
|---|---|---|
artifact_path | 模型在 run 内的相对路径 | 序列化时若为None会被剔除 |
run_id | 关联的 run ID | |
utc_time_created | 创建时间(UTC) | 默认取当前 UTC 时间,并去除时区信息以保持与旧版本行为一致 |
flavors | Flavor 名到"如何以该 Flavor 服务模型"的配置映射 | 默认为空字典 |
signature | 模型输入/输出/参数的 schema 定义 | 不能设置为False(False用于关闭自动推断) |
saved_input_example_info | 保存的输入示例元信息 | 如{"artifact_path": "input_example.json", "type": "dataframe", "pandas_orient": "split"} |
model_uuid | 模型唯一标识 | 默认由uuid.uuid4().hex生成 |
mlflow_version | 记录模型时使用的 MLflow 版本 | 默认取mlflow.version.VERSION |
metadata | 用户自定义元数据字典 | 会被写入MLmodel文件 |
model_size_bytes | 模型大小(字节) | 保存时自动计算 |
resources | 服务模型所需的资源声明 | 支持 YAML 文件路径或Resource对象列表 |
auth_policy | 服务模型所需的鉴权策略 | 与resources二选一 |
model_id/prompts | 新式 LoggedModel 关联与 Prompt 关联 |
Model的核心方法:
add_flavor(name, **params):为模型注册一种 Flavor 的服务方式,返回self支持链式调用;get_input_schema()/get_output_schema()/get_params_schema():读取签名中的输入、输出、参数 schema;get_serving_input(path)/load_input_example(path):读取随模型保存的 serving input 示例或原始 input example;to_dict()/to_yaml()/to_json()/save(path):序列化;序列化时会剔除空字段,因为部分 Model Serving 消费方无法正确处理空值;load(path)(类方法):从本地路径或远程 URI(如s3://)加载模型,支持直接指向MLmodel文件或所在目录;加载逻辑会解析models:/logged-model URI 并自动下载远端文件;from_dict(model_dict)(类方法):从字典还原模型,同时恢复signature与is_signature_from_type_hint等标志位。
一个典型的MLmodel文件(sklearn 模型)形如:
artifact_path: sklearn-model flavors: python_function: env: conda.yaml loader_module: mlflow.sklearn model_path: model.pkl python_version: 3.8.10 sklearn: pickled_model: model.pkl serialization_format: cloudpickle sklearn_version: 0.24.1 mlflow_version: 3.x.x model_uuid: 39ca11813cfc46b09ab83972740b80ca run_id: 8ede7df408dd42ed9fc39019ef7df309 utc_time_created: '2022-01-12 05:17:31.634689'ModelInfo类:log_model 的返回值
ModelInfo(mlflow/models/model.py)是log_model系列 API 返回的元数据对象。各属性如下:
| 属性 | 类型 | 说明 |
|---|---|---|
artifact_path | str | 模型在 run 内的相对路径 |
flavors | dict | Flavor 名 → 服务配置的映射 |
model_uri | str | 形如runs:/<run_id>/<artifact_path>(新式模型为models:/<model_id>) |
model_uuid | str | 模型 UUID(遗留字段) |
run_id | str | 关联 run 的 ID |
saved_input_example_info | dict | None | 输入示例的元信息 |
signature | ModelSignature | None | 模型签名 |
utc_time_created | str | 创建时间(UTC) |
mlflow_version | str | 记录时 MLflow 版本 |
metadata | dict | None | 用户自定义元数据 |
env_vars | list[str] | None | 记录模型过程中使用的环境变量 |
registered_model_version | int | None | 若注册到 Model Registry,则为版本号 |
prompts | list[str] | None | 关联的 Prompt URI 列表 |
model_id/metrics/params/tags/name/creation_timestamp | 见源码 | 新式 LoggedModel 关联字段 |
get_model_info(model_uri):按 URI 获取模型元数据
get_model_info(mlflow/models/model.py)接受任何受支持的模型 URI,返回ModelInfo:
/Users/me/path/to/local/model(本地路径)relative/path/to/local/model(相对路径)s3://my_bucket/path/to/model(对象存储)runs:/<mlflow_run_id>/run-relative/path/to/model(run 内路径)models:/<model_name>/<model_version>或models:/<model_name>/<stage>(Model Registry)mlflow-artifacts:/path/to/model(MLflow Artifacts 服务)
官方示例(摘自 docstring,可在 mlflow/models/model.py 中查看):
import mlflow import mlflow.models import mlflow.sklearn from sklearn.ensemble import RandomForestRegressor with mlflow.start_run() as run: params = {"n_estimators": 3, "random_state": 42} X = [[0, 1]] y = [1] signature = mlflow.models.infer_signature(X, y) rfr = RandomForestRegressor(**params).fit(X, y) mlflow.log_params(params) mlflow.sklearn.log_model(rfr, name="sklearn-model", signature=signature) model_uri = f"runs:/{run.info.run_id}/sklearn-model" model_info = mlflow.models.get_model_info(model_uri) model_signature = model_info.signature assert model_signature == signature签名系统:ModelSignature、infer_signature 与 set_signature
模型签名定义了模型输入、输出和推理参数的 schema,是模型可复现、可校验、可安全服务的基础。签名相关代码集中在 mlflow/models/signature.py。
ModelSignature:输入/输出/参数的 schema 容器
ModelSignature(inputs, outputs, params)由三个部分组成:输入Schema、输出Schema和参数ParamSchema(后两个可为None)。构造时要求三者至少提供一个,且inputs/outputs必须是Schema或 dataclass(dataclass 会被自动转换为 schema)。序列化接口包括:
to_dict():序列化为 JSON 可读字典,输入输出 schema 以 JSON 字符串形式嵌入(保证MLmodelYAML 的紧凑性);from_dict():反序列化;__eq__:基于输入、输出、参数三部分逐项比较。
infer_signature(model_input, model_output, params):自动推断签名
infer_signature(mlflow/models/signature.py)接受训练数据(输入)、模型预测(输出)与推理参数,返回ModelSignature。支持的输入类型包括:
pandas.DataFrame/pandas.Seriesdict[str, numpy.ndarray]numpy.ndarraypyspark.sql.DataFrame(其中DateType与TimestampType列都会被推断为datetime类型)scipy.sparse.csr_matrix/scipy.sparse.csc_matrix- JSON 可转换类型的字典或字典列表
params用于描述推理时的可调参数,例如 transformers 解码参数:
params = { "num_beams": 5, "max_length": 30, "do_sample": True, "remove_invalid_values": True, }当输入示例与 params 一起传入时(input_example=(data, params)),log_model/save_model会自动推断签名;之后可以在 pyfunc 预测时直接传入:
result = pyfunc_loaded.predict(data, params=params)从源码可见,推断失败时输入/输出 schema 会降级为Schema([ColSpec(type=AnyType())])(AnyType 类型在推理阶段不做数据校验),并打印 warning,因此签名推断是"尽力而为"的。
基于类型注解的签名推断(type hints)
signature.py还实现了从 Python 函数类型注解推断签名的机制(_infer_signature_from_type_hints,见 mlflow/models/signature.py):从predict函数的list[str]、list[dict[str, str]]等注解中解析出输入 schema,输出注解不可用则回退到AnyType。若函数未使用@mlflow.pyfunc.utils.pyfunc装饰器,会提示"decorate your function with@mlflow.pyfunc.utils.pyfuncto enable auto data validation against model input type hints"。
set_signature(model_uri, signature):为已记录模型补写签名
set_signature(mlflow/models/signature.py)用于为已记录的模型 artifacts 设置签名:流程为下载MLmodel文件 → 更新 signature → 回传覆盖。注意事项:
- 不支持
models:/<name>/<version>这类 Model Registry URI(Registry artifacts 只读),需要用runs:/或本地/对象存储路径; - 若 artifact 仓库禁止覆盖写入,该函数会失败;
- 官方示例:加载 run 中的模型,用测试集推断签名后回写:
import mlflow from mlflow.models import set_signature, infer_signature model_uri = f"runs:/{run_id}/models" model = mlflow.pyfunc.load_model(model_uri) predictions = model.predict(test_df) signature = infer_signature(test_df, predictions) set_signature(model_uri, signature)模型评估:evaluate、make_metric、MetricThreshold
模型评估 API 从mlflow.models.evaluation子包导出(见 mlflow/models/evaluation/init.py),主要成员包括:
evaluate(model, data, model_type, ...):对模型执行评估,返回EvaluationResult;make_metric(...):把自定义评估函数包装为可插拔的EvaluationMetric;MetricThreshold:定义阈值(如absolute_condition、greater_is_better),用于模型验证(model validation);EvaluationArtifact/EvaluationResult:评估过程中产生的 artifact 与评估结果容器;list_evaluators():列出可用评估器(如内置的回归、分类评估器)。
典型用法(参考 examples/evaluation 下的示例):
import mlflow from mlflow.models import evaluate evaluate( model="models:/my-model/1", data=eval_df, # pandas DataFrame,包含特征与真实标签列 model_type="regressor", # 或 "classifier" / "question-answering" 等 targets="y_true", )evaluate返回的EvaluationResult包含metrics(指标字典)、artifacts(如混淆矩阵、ROC 曲线图等评估产物)。结合 tests/evaluate 目录下的测试用例可以验证其行为,例如自定义指标通过make_metric注册后会在评估结果中体现。
预测与部署:predict 与 build_docker
mlflow.models.predict(model_uri, input_data, ...):免环境推理
predict(mlflow/models/python_api.py)根据模型的requirements.txt/conda.yaml自动重建环境并生成 JSON 格式预测,其参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
model_uri | 必填 | 模型 URI(本地路径、runs:/、s3://等) |
input_data | None | pyfunc 模型可接受的输入数据 |
input_path | None | 指向输入文件的路径,与input_data互斥 |
content_type | "json" | "json"或"csv" |
output_path | None | JSON 结果输出文件,缺省输出到 stdout |
env_manager | "virtualenv" | "virtualenv"/"uv"/"local"/"conda" |
install_mlflow | False | 环境激活后安装与调用方同版本的 mlflow |
pip_requirements_override | None | 覆盖模型依赖,用于测试依赖变更 |
extra_envs | None | 注入额外环境变量(仅 virtualenv/conda/uv 支持) |
代码示例(摘自 docstring,见 mlflow/models/python_api.py):
import mlflow # 基础预测 mlflow.models.predict( model_uri=f"runs:/{run_id}/model", input_data={"x": 1, "y": 2}, content_type="json", ) # 使用 uv 环境管理器(性能显著更优) mlflow.models.predict( model_uri=f"runs:/{run_id}/model", input_data={"x": 1, "y": 2}, env_manager="uv", ) # 覆盖依赖 + 注入环境变量 mlflow.models.predict( model_uri=f"runs:/{run_id}/model", input_data={"x": 1, "y": 2}, pip_requirements_override=["scikit-learn==0.23.2"], extra_envs={"OPENAI_API_KEY": "some_value"}, ) # 输出到文件 + 允许预发布版本 mlflow.models.predict( model_uri=f"runs:/{run_id}/model", input_data={"x": 1, "y": 2}, env_manager="uv", output_path="output.json", extra_envs={"UV_PRERELEASE": "allow"}, )源码要点(python_api.py):
- 使用
uv时必须确保 PATH 中存在uv命令,否则抛出MlflowException并提示安装方式; - 不使用时会在日志中"强烈推荐"改用
uv; content_type="json"时输入数据会经convert_input_example_to_serving_input序列化与校验;"csv"时则转换为 DataFrame 的 CSV 表示;- 底层通过
get_flavor_backend(...).predict(...)调用 pyfunc 后端(mlflow/models/flavor_backend_registry.py)。
mlflow.models.build_docker(...):构建服务镜像
build_docker(mlflow/models/python_api.py)构建一个默认入口在8080 端口提供服务的 Docker 镜像(pyfunc Flavor),参数如下:
| 参数 | 默认值 | 说明 |
|---|---|---|
model_uri | None | 模型 URI;若省略,需将模型目录挂载到容器/opt/ml/model |
name | "mlflow-pyfunc" | 镜像名 |
env_manager | "virtualenv" | virtualenv/conda/local |
mlflow_home | None | 本地 MLflow 克隆路径(仅开发用) |
install_java | False | 是否安装 Java;johnsnowlabs、h2o、sparkFlavor 会自动开启 |
install_mlflow | False | 环境激活后安装 mlflow |
base_image | None | 基础镜像;缺省为ubuntu:24.04或python:{version}-slim |
镜像内默认启动 nginx 与 uvicorn 进程;若部署到 Google Cloud Run 等平台,可通过环境变量关闭 nginx:
docker run -p 5001:8080 -e DISABLE_NGINX=true "my-image-name"依赖管理:infer_pip_requirements 与 update_model_requirements
infer_pip_requirements(model_path, flavor, fallback=None):通过加载模型反向推断其 pip 依赖,返回按字母序排序的依赖列表(可从 mlflow/utils/environment.py 查看实现)。update_model_requirements(model_uri, operation, requirement_list)(mlflow/models/model.py):对模型的conda.yaml与requirements.txt执行"添加/移除"依赖,流程为下载这两个文件 → 更新 → 回传覆盖。要点:operation仅支持"add"或"remove";- 添加时若依赖已存在则覆盖版本,否则追加;移除时忽略版本说明符、只按包名删除,不存在的包会被忽略;
- 不支持
models:/<name>/<version>Registry URI,因为 Registry artifacts 只读;但runs:/和mlflow-artifacts:/可用; - 配合
predict(pip_requirements_override=...)先验证新依赖,确认后再更新,可避免重新记录模型。
模型即代码与配套工具函数
set_model(model):模型即代码(Model-as-Code)
set_model(mlflow/models/model.py)用于在"模型即代码"场景下指定要记录的模型对象,支持的模型类型:
- Python 函数或可调用对象;
PythonModel实例;- LangChain 模型(
Runnable)或指向 LangChain 模型的路径; - LlamaIndex index 或对应路径。
内部通过__mlflow_model__全局变量传递,LangChain/LlamaIndex 类型分别由_validate_langchain_model/_validate_llama_index_model校验(见 mlflow/models/model.py)。配合示例 examples/pyfunc/model_as_code.py 与 examples/pyfunc/model_as_code_driver.py 可以了解完整用法。
mlflow.models.utils中的工具函数
从 mlflow/models/init.py 可见,mlflow.models还导出了一批实用函数(实现见 mlflow/models/utils.py):
ModelInputExample:输入示例的类型别名(DataFrame、ndarray、dict、list、稀疏矩阵、str、bytes、tuple);convert_input_example_to_serving_input(example):把训练阶段的输入示例转换为 serving 阶段的标准 JSON(支持dataframe_split格式);validate_schema(data, schema, params=None):按签名校验数据;validate_serving_input(model_uri, serving_input):校验 serving 输入能否被模型接受;add_libraries_to_model(model_uri, run_id=None, registered_model_name=None):把模型运行所需库文件打包进模型(wheel 化);set_retriever_schema(...)(来自dependencies_schemas):为 RAG/检索类模型声明检索器 schema。
此外,ModelConfig(mlflow/models/model_config.py)提供模型配置文件解析能力——log_model时传入model_config(JSON/YAML 路径或字典)会被扁平化为/分隔的 params 记录到 run(见 mlflow/models/model.py 的_flatten_nested_params逻辑);Resource/ResourceType(mlflow/models/resources.py)用于声明模型服务所需的资源(如 UC 函数、向量索引),从 YAML 文件或对象列表解析后写入MLmodel。
源码验证与测试入口
如果你想深入验证本文所述行为,可以查看以下仓库路径:
- 模块导出清单与全部公开符号:mlflow/models/init.py
- 核心元数据实现(
Model/ModelInfo/get_model_info/update_model_requirements):mlflow/models/model.py - 签名推断与设置:mlflow/models/signature.py
- 预测与 Docker 构建:mlflow/models/python_api.py
- 评估 API:mlflow/models/evaluation、测试见 tests/evaluate
- Flavor 后端注册:mlflow/models/flavor_backend_registry.py
- 端到端示例:examples/evaluation、examples/pyfunc、examples/sklearn_autolog
- 模块级测试:tests/models 与 tests/pyfunc
总结
mlflow.models是 MLflow 模型管线的"心脏":Model定义标准的MLmodel资产格式,ModelSignature/infer_signature保证输入输出可校验,evaluate提供离线质量评估,predict/build_docker打通从训练到推理的最后一步,而set_model、ModelConfig、Resource等新 API 则把 MLflow 从传统 ML 扩展到了 Agent / LLM 应用场景。无论你使用 sklearn 等经典框架,还是 LangChain / LlamaIndex 等 GenAI 栈,都可以从这套统一的模型抽象中获益。
【免费下载链接】mlflowThe open source AI engineering platform for agents, LLMs, and ML models. MLflow enables teams of all sizes to debug, evaluate, monitor, and optimize production-quality AI applications while controlling costs and managing access to models and data.项目地址: https://gitcode.com/GitHub_Trending/ml/mlflow
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考