跳到主要内容

MLflow 模型中的依赖管理

MLflow 模型是一种标准的格式,它将机器学习模型与其依赖项和其他元数据打包在一起。构建带有依赖项的模型可以提高跨各种平台和工具的可复现性和可移植性。

例如,当您使用 MLflow Tracking API 创建 MLflow 模型时,例如 mlflow.pytorch.log_model(),MLflow 会自动推断您正在使用的模型类型的所需依赖项,并将它们记录为模型元数据的一部分。然后,当您为预测服务模型时,MLflow 会自动在环境中安装依赖项。因此,您通常不需要担心 MLflow 模型中的依赖管理。

但是,在某些情况下,您可能需要添加或修改一些依赖项。本文档提供了一个高级概述,说明 MLflow 如何管理依赖项,以及如何根据您的用例自定义依赖项的指南。

提示

提高 MLflow 依赖项推断准确性的一项技巧是在保存模型时添加 input_example。这使得 MLflow 能够在保存模型之前执行模型预测,从而捕获预测过程中使用的依赖项。有关此参数的更多详细用法,请参阅 模型输入示例

MLflow 如何记录模型依赖项

MLflow 模型保存在指定目录中,其结构如下:

my_model/
├── MLmodel
├── model.pkl
├── conda.yaml
├── python_env.yaml
└── requirements.txt

模型依赖项由以下文件定义(其他文件请参阅讨论 存储格式 的部分提供的指南):

  • python_env.yaml - 此文件包含使用 virtualenv 恢复模型环境所需的信息(1)Python 版本(2)pip、setuptools 和 wheel 等构建工具(3)模型的 pip 需求(对 requirements.txt 的引用)。
  • requirements.txt - 定义运行模型所需的 pip 依赖项集。
  • conda.yaml - 定义运行模型所需的 conda 环境。当您将 conda 指定为恢复模型环境的环境管理器时,将使用此文件。

请注意,不建议手动编辑这些文件来添加或删除依赖项。它们由 MLflow 自动生成,您手动所做的任何更改将在您再次保存模型时被覆盖。相反,您应该使用以下各节中描述的推荐方法之一。

使用 MLFLOW_LOCK_MODEL_DEPENDENCIES 锁定模型依赖项

注意

MLflow 2.16.0 及更高版本可用

MLflow 可以在记录模型时自动将直接和传递的模型依赖项锁定到其确切版本。这通过捕获模型创建时的完整依赖项树来确保可复现性。

要启用依赖项锁定,请设置 MLFLOW_LOCK_MODEL_DEPENDENCIES 环境变量。

export MLFLOW_LOCK_MODEL_DEPENDENCIES=true

启用后,MLflow 将使用 uv(如果已安装)来解析和锁定所有依赖项,包括它们的传递依赖项。然后,锁定后的需求将保存在模型的 requirements.txt 文件中。

无锁定示例(默认)

mlflow==2.9.2
scikit-learn==1.3.2
cloudpickle==3.0.0

启用锁定的示例

mlflow==2.9.2
scikit-learn==1.3.2
cloudpickle==3.0.0
numpy==1.24.3
scipy==1.11.4
joblib==1.3.2
threadpoolctl==3.2.0
# ... other transitive dependencies
提示

依赖项锁定需要安装 uv。如果 uv 不可用,MLflow 将跳过锁定步骤并使用标准的依赖项推断。使用以下命令安装 uv

pip install uv
警告

锁定依赖项可能会显著增加 requirements.txt 文件的大小,因为它包含了所有传递依赖项。这提供了更好的可复现性,但可能会使环境更加僵化。

示例

以下是在使用 mlflow.sklearn.log_model 记录模型时 MLflow 生成的环境文件示例:

  • python_env.yaml
python: 3.9.8
build_dependencies:
- pip==23.3.2
- setuptools==69.0.3
- wheel==0.42.0
dependencies:
- -r requirements.txt
  • requirements.txt
mlflow==2.9.2
scikit-learn==1.3.2
cloudpickle==3.0.0
  • conda.yaml
name: mlflow-env
channels:
- conda-forge
dependencies:
- python=3.9.8
- pip
- pip:
- mlflow==2.9.2
- scikit-learn==1.3.2
- cloudpickle==3.0.0

向 MLflow 模型添加额外依赖项

MLflow 会推断模型类型库所需的依赖项,但您的模型可能依赖于其他库,例如数据预处理。在这种情况下,您可以通过在记录模型时指定 extra_pip_requirements 参数来向模型添加额外依赖项。例如:

import mlflow


class CustomModel(mlflow.pyfunc.PythonModel):
def predict(self, context, model_input):
# your model depends on pandas
import pandas as pd

...
return prediction


# Log the model
mlflow.pyfunc.log_model(
python_model=CustomModel(),
name="model",
extra_pip_requirements=["pandas==2.0.3"],
input_example=input_data,
)

这些额外依赖项将按如下方式添加到 requirements.txt(并且类似地添加到 conda.yaml):

mlflow==2.9.2
cloudpickle==3.0.0
pandas==2.0.3 # added

在这种情况下,MLflow 在为预测服务模型时,除了推断出的依赖项外,还将安装 Pandas 2.0.3。

注意

记录带有依赖项的模型后,建议在沙箱环境中进行测试,以避免在将模型部署到生产环境时出现任何依赖项问题。自 MLflow 2.10.0 起,您可以使用 mlflow.models.predict() API 在虚拟环境中快速测试您的模型。有关更多详细信息,请参阅 验证预测环境

自己定义所有依赖项

或者,您也可以从头开始定义所有依赖项,而不是添加额外的依赖项。为此,请在记录模型时指定 pip_requirements。例如:

import mlflow

# Log the model
mlflow.sklearn.log_model(
sk_model=model,
name="model",
pip_requirements=[
"mlflow-skinny==2.9.2",
"cloudpickle==2.5.8",
"scikit-learn==1.3.1",
],
)

手动定义的依赖项将覆盖 MLflow 从模型类型库检测到的默认依赖项。

mlflow-skinny==2.9.2
cloudpickle==2.5.8
scikit-learn==1.3.1
警告

请注意,声明与训练期间使用的依赖项不同的依赖项可能很危险,并且容易出现意外行为。确保一致性的最安全方法是依赖 MLflow 推断出的默认依赖项。

注意

记录带有依赖项的模型后,建议在沙箱环境中进行测试,以避免在将模型部署到生产环境时出现任何依赖项问题。自 MLflow 2.10.0 起,您可以使用 mlflow.models.predict() API 在虚拟环境中快速测试您的模型。有关更多详细信息,请参阅 验证预测环境

使用 MLflow 模型保存额外代码依赖项 - 自动推断

注意

目前仅支持 Python 函数模型的自动代码依赖项推断。MLflow 的未来版本将支持其他命名模型类型。

在 MLflow 2.13.0 版本中,引入了一种包含自定义依赖代码的新方法,该方法扩展了保存或记录模型时声明 code_paths 的现有功能。此新功能利用导入依赖项分析,通过检查 Python 模型定义中的引用导入了哪些模块来自动推断模型所需的代码依赖项。

为了使用此新功能,您只需在记录时将参数 infer_code_paths(默认值为 False)设置为 True。利用此方法进行依赖项推断时,您无需像 MLflow 2.13.0 之前那样通过声明 code_paths 目录位置来显式定义文件位置。

下面是一个使用此功能的示例,其中我们正在记录一个包含外部依赖项的模型。在第一部分中,我们定义了一个名为 custom_code 的外部模块,它存在于不同于我们的模型定义的位置。

custom_code.py
from typing import List

iris_types = ["setosa", "versicolor", "viginica"]


def map_iris_types(predictions: int) -> List[str]:
return [iris_types[pred] for pred in predictions]

定义了此 custom_code.py 模块后,它就可以在我们的 Python 模型中使用:

model.py
from typing import Any, Dict, List, Optional

from custom_code import map_iris_types # import the external reference

import mlflow


class FlowerMapping(mlflow.pyfunc.PythonModel):
"""Custom model with an external dependency"""

def predict(
self, context, model_input, params: Optional[Dict[str, Any]] = None
) -> List[str]:
predictions = [pred % 3 for pred in model_input]

# Call the external function
return map_iris_types(predictions)


with mlflow.start_run():
model_info = mlflow.pyfunc.log_model(
name="flowers",
python_model=FlowerMapping(),
infer_code_paths=True, # Enabling automatic code dependency inference
)

infer_code_paths 设置为 True 时,将分析 map_iris_types 的依赖项,将其源声明检测为源自 custom_code.py 模块,并将 custom_code.py 中的代码引用与模型工件一起存储。请注意,使用 code_paths 参数(在下一节讨论)定义外部代码依赖项不是必需的。

提示

只有当前工作目录中的模块才可访问。依赖项推断不能跨越模块边界,也不能在你自定义的代码定义在完全不同的库中时工作。如果你的代码库结构使得常用模块完全在模型记录代码正在执行的路径之外,则需要使用原始的 code_paths 选项来记录这些依赖项,因为 infer_code_paths 依赖项推断将无法捕获这些需求。

infer_code_paths 的限制

警告

在使用 infer_code_paths 进行依赖项推断之前,请确保你的依赖代码模块中没有硬编码敏感数据(例如,密码、访问令牌或机密)。代码推断不会混淆敏感信息,并且会捕获并记录(保存)模块,无论它包含什么。

在使用 infer_code_paths 时,关于代码结构的一个重要方面是避免在代码的主入口点中定义依赖项。当 Python 代码文件被加载为 __main__ 模块时,它不能被推断为代码路径文件。这意味着,如果你直接运行脚本(例如,使用 python script.py),则在该脚本中定义的函数和类将成为 __main__ 模块的一部分,而其他模块将不易访问。

如果你的模型依赖于这些类或函数,这可能会造成问题,因为它们不是标准模块命名空间的一部分,因此不容易序列化。为了处理这种情况,你应该使用 cloudpickle 来序列化你的模型实例。 cloudpickle 是 Python 的 pickle 模块的一个扩展版本,它可以序列化更广泛的 Python 对象,包括在 __main__ 模块中定义的函数和类。

为什么这很重要

  • 代码路径推断:MLflow 使用代码路径来理解和记录与你的模型相关的代码。当脚本作为 __main__ 执行时,代码路径无法推断,这使得跟踪和复现你的 MLflow 实验变得复杂。
  • 序列化:标准的序列化方法(如 pickle)可能无法与 __main__ 模块对象一起工作,这会在尝试保存和加载模型时导致问题。cloudpickle 通过允许序列化这些对象来提供解决方案,确保你的模型能够被正确保存和恢复。

最佳实践

  • 避免在 __main__ 模块中定义关键函数和类。相反,将它们放在单独的模块文件中,可以根据需要导入。
  • 如果你必须在 __main__ 模块中定义函数和类,请使用 cloudpickle 来序列化你的模型,以确保所有依赖项都得到正确处理。

使用 MLflow 模型保存额外代码 - 手动声明

MLflow 还支持将你的自定义 Python 代码保存为模型的依赖项。当你想部署模型所需的自定义模块进行预测时,这特别有用。要做到这一点,请在记录模型时指定 code_paths。例如,如果你的项目有以下文件结构:

my_project/
├── utils.py
└── train.py
train.py
import mlflow


class MyModel(mlflow.pyfunc.PythonModel):
def predict(self, context, model_input):
from utils import my_func

x = my_func(model_input)
# .. your prediction logic
return prediction


# Log the model
with mlflow.start_run() as run:
mlflow.pyfunc.log_model(
python_model=MyModel(),
name="model",
input_example=input_data,
code_paths=["utils.py"],
)

然后 MLflow 将在模型目录下的 code/ 目录中保存 utils.py

model/
├── MLmodel
├── ...
└── code/
└── utils.py

当 MLflow 加载模型进行服务时,code 目录将被添加到系统路径中,因此你可以像 from utils import my_func 一样在你的模型代码中使用该模块。你也可以将目录路径指定为 code_paths 来保存目录下的多个文件。

对自定义库使用 code_paths 选项

要包含在 PyPI 上不可用的自定义库,可以在记录模型时使用 code_paths 参数。此选项允许你上传 .whl 文件或其他依赖项与你的模型一起,确保在服务时所有必需的库都可用。

警告

以下示例演示了一种包含自定义库以用于开发目的的快速方法。不建议在生产环境中使用此方法。对于生产环境,请将库上传到自定义 PyPI 服务器或云存储,以确保可靠和安全的访问。

例如,假设你的项目有以下文件结构:

my_project/
|── train.py
└── custom_package.whl

然后以下代码可以记录你的模型以及自定义包:

train.py
import mlflow
from custom_package import my_func


class MyModel(mlflow.pyfunc.PythonModel):
def predict(self, context, model_input):
x = my_func(model_input)
# .. your prediction logic
return prediction


# Log the model
with mlflow.start_run() as run:
mlflow.pyfunc.log_model(
python_model=MyModel(),
name="model",
extra_pip_requirements=["code/custom_package.whl"],
input_example=input_data,
code_paths=["custom_package.whl"],
)

code_paths 选项的注意事项

使用 code_paths 选项时,请注意,指定的单个文件或目录必须与你的模型脚本位于同一目录中。如果指定的单个文件或目录位于父目录或子目录(例如 my_project/src/utils.py)中,模型服务将因 ModuleNotFoundError 而失败。例如,假设你的项目具有以下文件结构:

my_project/
|── train.py
└── src/
└── utils.py

那么以下模型代码不起作用

class MyModel(mlflow.pyfunc.PythonModel):
def predict(self, context, model_input):
from src.utils import my_func

# .. your prediction logic
return prediction


with mlflow.start_run() as run:
mlflow.pyfunc.log_model(
python_model=MyModel(),
name="model",
input_example=input_data,
code_paths=[
"src/utils.py"
], # the file will be saved at code/utils.py not code/src/utils.py
)

# => Model serving will fail with ModuleNotFoundError: No module named 'src'

此限制是由于 MLflow 保存和加载指定文件及目录的方式。当它将 code/ 目标下的指定文件或目录复制到 code/ 时,它不会保留它们最初所在的相对路径。例如,在上面的示例中,MLflow 会将 utils.py 复制到 code/utils.py,而不是 code/src/utils.py。因此,它必须导入为 from utils import my_func,而不是 from src.utils import my_func。然而,这可能不令人满意,因为导入路径与原始训练脚本不同。

为了解决这个问题,code_paths 应该指定父目录,在本例中是 code_paths=["src"]。这样,MLflow 将会把整个 src/ 目录复制到 code/ 下,你的模型代码将能够导入 src.utils

class MyModel(mlflow.pyfunc.PythonModel):
def predict(self, context, model_input):
from src.utils import my_func

# .. your prediction logic
return prediction


with mlflow.start_run() as run:
mlflow.pyfunc.log_model(
python_model=model,
name="model",
input_example=input_data,
code_paths=["src"], # the whole /src directory will be saved at code/src
)
警告

同样的原因,code_paths 选项也无法处理相对导入 code_paths=["../src"]

code_paths 在加载具有相同模块名但不同实现的多个模型时的限制

code_paths 选项的当前实现存在一个限制,即它不支持在同一 Python 进程中加载依赖于具有相同名称但不同实现的模块的多个模型,如下例所示:

import importlib
import sys
import tempfile
from pathlib import Path

import mlflow

with tempfile.TemporaryDirectory() as tmpdir:
tmpdir = Path(tmpdir)
my_model_path = tmpdir / "my_model.py"
code_template = """
import mlflow

class MyModel(mlflow.pyfunc.PythonModel):
def predict(self, context, model_input):
return [{n}] * len(model_input)
"""

my_model_path.write_text(code_template.format(n=1))

sys.path.insert(0, str(tmpdir))
import my_model

# model 1
model1 = my_model.MyModel()
assert model1.predict(context=None, model_input=[0]) == [1]

with mlflow.start_run():
info1 = mlflow.pyfunc.log_model(
name="model",
python_model=model1,
code_paths=[my_model_path],
)

# model 2
my_model_path.write_text(code_template.format(n=2))
importlib.reload(my_model)
model2 = my_model.MyModel()
assert model2.predict(context=None, model_input=[0]) == [2]

with mlflow.start_run():
info2 = mlflow.pyfunc.log_model(
name="model",
python_model=model2,
code_paths=[my_model_path],
)

# To simulate a fresh Python process, remove the `my_model` module from the cache
sys.modules.pop("my_model")

# Now we have two models that depend on modules with the same name but different implementations.
# Let's load them and check the prediction results.
pred = mlflow.pyfunc.load_model(info1.model_uri).predict([0])
assert pred == [1], pred # passes

# As the `my_model` module was loaded and cached in the previous `load_model` call,
# the next `load_model` call will reuse it and return the wrong prediction result.
assert "my_model" in sys.modules
pred = mlflow.pyfunc.load_model(info2.model_uri).predict([0])
assert pred == [2], pred # doesn't pass, `pred` is [1]

为了解决此限制,您可以在加载模型之前从缓存中删除该模块。例如:

model1 = mlflow.pyfunc.load_model(info1.model_uri)
sys.modules.pop("my_model")
model2 = mlflow.pyfunc.load_model(info2.model_uri)

另一种解决方法是为不同的实现使用不同的模块名。例如:

mlflow.pyfunc.log_model(
name="model1",
python_model=model1,
code_paths=["my_model1.py"],
)

mlflow.pyfunc.log_model(
name="model",
python_model=model2,
code_paths=["my_model2.py"],
)

考虑到 code_paths 的这一限制,推荐的项目结构如下:

my_project/
|-- model.py # Defines the custom pyfunc model
|── train.py # Trains and logs the model
|── core/ # Required modules for prediction
| |── preprocessing.py
| └── ...
└── helper/ # Other helper modules used for training, evaluation
|── evaluation.py
└── ...

这样,您就可以使用 code_paths=["core"] 来记录模型,以包含预测所需的模块,同时排除仅用于开发的辅助模块。

验证预测环境

在部署之前验证模型是确保生产就绪的关键步骤。MLflow 提供了几种在本地测试模型的方法,可以在虚拟环境或 Docker 容器中进行。如果在验证过程中发现任何依赖项问题,请遵循 如何在服务我的模型时修复依赖项错误? 中的指南。

使用虚拟环境进行离线预测测试

您可以使用 MLflow Models 的 predict API(通过 Python 或 CLI)对模型进行测试预测。这将从模型 URI 加载您的模型,创建包含模型依赖项(在 MLflow 模型中定义)的虚拟环境,并使用该模型运行离线预测。有关 predict API 的更详细用法,请参阅 mlflow.models.predict()CLI 参考

注意

Python API 自 MLflow 2.10.0 起可用。如果您使用的是旧版本,请使用 CLI 选项。

import mlflow

mlflow.models.predict(
model_uri="runs:/<run_id>/model",
input_data="<input_data>",
)

使用 mlflow.models.predict() API 可以方便地快速测试模型和推理环境。但是,它可能不是服务的一个完美模拟,因为它不会启动在线推理服务器。不过,它是测试预测输入是否正确格式化的好方法。

格式化受您的模型日志记录的 predict() 方法支持的类型约束。如果模型是使用签名记录的,则可以通过 MLflow UI 或 mlflow.models.get_model_info() 查看输入数据,该信息包含 signature 字段。

更广泛地说,MLflow 能够支持各种特定类型的输入类型,例如 tensorflow 张量。MLflow 还支持不特定于给定类型的类型,例如 pandas DataFrame、numpy ndarray、python Dict、python List、scipy.sparse 矩阵和 spark DataFrame。

使用虚拟环境测试在线推理端点

如果您想通过实际运行在线推理服务器来测试模型,可以使用 MLflow serve API。这会创建一个包含模型及其依赖项的虚拟环境,类似于 predict API,但会启动推理服务器并公开 REST 端点。然后,您可以发送测试请求并验证响应。有关 serve API 的更详细用法,请参阅 CLI 参考

mlflow models serve -m runs:/<run_id>/model -p <port>
# In another terminal
curl -X POST -H "Content-Type: application/json" \
--data '{"inputs": [[1, 2], [3, 4]]}' \
https://:<port>/invocations

虽然这是部署前测试模型的可靠方法,但有一个注意事项是,虚拟环境不会吸收您机器和生产环境之间的操作系统级别差异。例如,如果您将 MacOS 用作本地开发机,但您的部署目标运行在 Linux 上,您可能会遇到一些在虚拟环境中无法复现的问题。

在这种情况下,您可以使用 Docker 容器来测试您的模型。虽然它不像虚拟机那样提供完整的操作系统级别隔离(例如,我们无法在 Linux 机器上运行 Windows 容器),但 Docker 涵盖了一些常见的测试场景,例如运行不同版本的 Linux 或在 Mac 或 Windows 上模拟 Linux 环境。

使用 Docker 容器测试在线推理端点

MLflow 的 CLI 和 Python build-docker API 能够构建一个基于 Ubuntu 的 Docker 镜像来服务您的模型。该镜像将包含您的模型和依赖项,并且还有一个用于启动推理服务器的入口点。与 serve API 类似,您可以发送测试请求并验证响应。有关 build-docker API 的更详细用法,请参阅 CLI 参考

mlflow models build-docker -m runs:/<run_id>/model -n <image_name>
docker run -p <port>:8080 <image_name>
# In another terminal
curl -X POST -H "Content-Type: application/json" \
--data '{"inputs": [[1, 2], [3, 4]]}' \
https://:<port>/invocations

故障排除

如何在服务我的模型时修复依赖项错误

模型部署期间最常见的问题之一围绕着依赖项问题。在记录或保存模型时,MLflow 会尝试推断模型依赖项并将其作为 MLflow 模型元数据的一部分保存。但是,这可能并不总是完整的,可能会遗漏某些依赖项,例如某些库的 [extras] 依赖项。这可能导致服务模型时出现错误,例如 "ModuleNotFoundError" 或 "ImportError"。以下是一些可以帮助诊断和修复缺失依赖项错误的步骤。

提示

为了降低依赖项错误的发生概率,您可以在保存模型时添加 input_example。这使得 MLflow 能够在保存模型之前执行模型预测,从而捕获预测过程中使用的依赖项。有关此参数的更多详细用法,请参阅 模型输入示例

1. 检查缺失的依赖项

缺失的依赖项列在错误消息中。例如,如果您看到以下错误消息:

ModuleNotFoundError: No module named 'cv2'

2. 尝试使用 predict API 添加依赖项

现在您知道了缺失的依赖项,可以创建一个带有正确依赖项的新模型版本。但是,为尝试新依赖项而创建新模型可能有点麻烦,特别是因为您可能需要多次迭代才能找到正确的解决方案。相反,您可以使用 mlflow.models.predict() API 来测试您的更改,而无需在故障排除安装错误时反复重新记录模型。

为此,请使用 pip-requirements-override 选项来指定 pip 依赖项,例如 opencv-python==4.8.0

import mlflow

mlflow.models.predict(
model_uri="runs:/<run_id>/<model_path>",
input_data="<input_data>",
pip_requirements_override=["opencv-python==4.8.0"],
)

指定的依赖项将安装到虚拟环境中,除了(或代替)模型元数据中定义的依赖项。由于这不会修改模型,因此您可以快速安全地迭代以找到正确的依赖项。

请注意,对于 Python 实现中的 input_data 参数,该函数接受由模型的 predict() 函数支持的 Python 对象。一些示例可能包括特定于类型的输入,如 tensorflow 张量,或更通用的类型,如 pandas DataFrame、numpy ndarray、python Dict 或 python List。在使用 CLI 时,我们无法传递 Python 对象,而是查找传递包含输入有效负载的 CSV 或 JSON 文件的路径。

注意

pip-requirements-override 选项自 MLflow 2.10.0 起可用。

3. 更新模型元数据

找到正确的依赖项后,您可以使用 mlflow.models.update_model_requirements() API 更新记录模型的依赖项。

import mlflow

mlflow.models.update_model_requirements(
model_uri="runs:/<run_id>/<model_path>",
operation="add",
requirement_list=["opencv-python==4.8.0"],
)

请注意,您也可以利用 CLI 来更新模型需求:

mlflow models update-pip-requirements -m runs:/<run_id>/<model_path> add "opencv-python==4.8.0"

或者,您可以通过在记录模型时指定 extra_pip_requirements 选项来记录具有更新依赖项的新模型。

import mlflow

mlflow.pyfunc.log_model(
name="model",
python_model=python_model,
extra_pip_requirements=["opencv-python==4.8.0"],
input_example=input_data,
)

如何启用在 mlflow.models.predict 中安装预发布版本

如果您使用 mlflow.models.predict 在服务之前验证模型并遇到类似以下错误:

hint: `mlflow-skinny` was requested with a pre-release marker (e.g.,
mlflow-skinny==3.2.0rc0), but pre-releases weren't enabled (try:
`--prerelease=allow`)

您可以通过 extra_envs 字段设置环境变量 UV_PRERELEASE=allow 来解决它。这使得 uv 在环境设置期间能够安装预发布包。

mlflow.models.predict(
model_uri=model_info.model_uri,
input_data=["a", "b", "c"],
extra_envs={"UV_PRERELEASE": "allow"},
)

如何迁移 Anaconda 依赖项以应对许可变更

Anaconda Inc. 更新了其 服务条款,适用于 anaconda.org 频道。根据新的服务条款,如果您依赖于 Anaconda 的打包和分发,您可能需要商业许可。有关更多信息,请参阅 Anaconda Commercial Edition FAQ。您对任何 Anaconda 频道的任何使用均受其服务条款的约束。

在 MLflow v1.18 之前的版本中记录的 MLflow 模型默认使用 conda defaults 频道(https://repo.anaconda.com/pkgs)作为依赖项。由于此许可更改,MLflow 已停止使用 defaults 频道来记录使用 MLflow v1.18 及更高版本记录的模型。现在默认记录的频道是 conda-forge,它指向社区管理的 https://forge.conda.org.cn

如果您在 MLflow v1.18 之前记录了模型,而没有从该模型的 conda 环境中排除 defaults 频道,则该模型可能存在您可能不希望的对 defaults 频道的依赖。要手动确认模型是否具有此依赖项,您可以检查随记录模型打包的 conda.yaml 文件中的 channel 值。例如,具有 defaults 频道依赖项的模型 conda.yaml 可能如下所示:

name: mlflow-env
channels:
- defaults
dependencies:
- python=3.8.8
- pip
- pip:
- mlflow==2.3
- scikit-learn==0.23.2
- cloudpickle==1.6.0

如果您想更改模型环境中使用的频道,您可以使用 log_model()conda_env 参数指定频道,将模型重新注册到模型注册表,并附带一个新的 conda.yaml

有关 log_model() API 的更多信息,请参阅您正在使用的模型类型的 MLflow 文档,例如 mlflow.sklearn.log_model()