Snowflake Model Registry

备注

本主题中描述的模型注册表 API 从包版本 1.5.0 开始正式发布。

训练模型后,在 Snowflake 中操作模型和运行推理时,首先要在 Snowflake Model Registry 中记录模型。Model Registry 可让您在 Snowflake 中安全地管理模型及其元数据,而不受来源和类型的限制,让推理运行变得简单。Snowflake Model Registry 的主要优势和功能如下:

  • 能够存储和管理模型版本、模型指标和其他模型元数据

  • 能够使用 Python、SQL 或 REST API 端点提供模型并大规模运行分布式推理

  • 能够通过灵活的治理选项管理模型生命周期,从开发到生产的环境中使用模型

  • 能够使用 Snowflake ML Observability 监控模型性能和偏移

  • 能够通过基于角色的访问控制安全地管理模型访问权限

Model Registry 将机器学习模型存储为 Snowflake 中的出色架构级对象。

记录模型后,您可以调用其方法(相当于函数或存储过程),在 Snowflake 虚拟仓库 中执行模型操作(例如 推理),或者在 Snowpark Container Services 中为服务提供 基于 GPU 的推理

Snowflake Model Registry 为大多数常见模型类型提供 内置类型,包括 scikit-learnxgboost、LightGBM、PyTorch、TensorFlow、Hugging Face 管道MLFlow pyfunc 模型。Model Registry 还足够灵活和强大,支持您自己先前训练的模型以及任何自定义处理代码。

小技巧

请在 示例和快速入门 中查看这些具有端到端工作流程的模型类型的示例。

Snowflake Model Registry Python API 中的主要类如下:

本主题介绍如何使用 Snowpark snowflake-ml-python 库在 Python 中执行注册表操作。您还可以在 SQL 中执行许多注册表操作,请参阅 Model Registry SQL

所需权限

若要创建模型,您必须拥有创建模型的架构,或者拥有其 CREATE MODEL 权限。要使用模型,您必须拥有该模型或拥有该模型的 USAGE 权限。USAGE 权限允许被授权方使用模型进行推理,但不能查看其任何内部内容。要允许用户访问架构中的所有现有模型,请使用 GRANT USAGE ON ALL MODELS IN SCHEMA <schema> TO ROLE <role>; 您还可以通过 GRANT USAGE ON FUTURE MODELS IN SCHEMA <schema> TO ROLE <role> 允许用户访问架构中自动创建的未来模型;

如果用户的角色对模型具有 USAGE,则它会在 Snowsight model registry 页面 中显示。有关权限如何在 Snowflake 中起作用的详细信息,请参阅 访问控制权限

备注

默认情况下,模型当前不支持 Replication。该功能是 BCR 捆绑包 2024_08 的一部分,如果您需要复制模型,可以启用该功能。该功能将很快默认启用。

当前限制

以下限制适用于模型和模型版本:

模型

  • 最多 1000 个版本

模型版本

  • 最多 10 个方法

  • 最多 10 次导入

  • 每个方法最多 500 个实参

  • 最大元数据(包括指标)为 100 KB

  • 最大模型总大小为 5 GB (用于仓库部署模型)

  • 最大配置文件大小为 250 KB,其中包括 conda.ymllog_model 在内部生成的其他清单文件。(例如,如果模型具有许多函数,并且所有函数都有许多实参,则可能会超出此限制。)

打开 Snowflake Model Registry

模型是一级 Snowflake 对象,可以与其他 Snowflake 对象一起组织到数据库和架构内。Snowflake Model Registry 提供了一个 Python 类来在架构内管理模型。因此,任何 Snowflake 架构均可用作注册表。不必为此目的初始化或准备架构。Snowflake 建议为此目的创建一个或多个专用架构,例如 ML.REGISTRY。您可以使用 CREATE SCHEMA 创建架构。

在注册表中创建或修改模型之前,必须打开注册表。打开注册表将返回其引用,然后您可以使用该引用来添加新模型,并获取对现有模型的引用。

from snowflake.ml.registry import Registry

reg = Registry(session=sp_session, database_name="ML", schema_name="REGISTRY")
Copy

注册模型和版本

将模型添加到注册表中的操作称为 登记 模型。通过调用注册表的 log_model 方法来登记模型。此模型序列化模型(Python 对象),并通过它创建 Snowflake 模型对象。此方法还会将元数据(例如描述)添加到 log_model 调用中指定的模型。

每个模型的版本数量不受限制。要登记模型的其他版本,请再次调用具有相同 model_name 但不同 version_namelog_model

当模型被添加到注册表时,您不能向模型添加标签,因为标签是模型的属性,log_model 会添加特定的模型版本,只有在添加模型的第一个版本时才会创建模型。您可以在登记模型的第一个版本后 更新模型的标签

在下面的示例中,clf`(“classifier”的缩写)是已在代码中其他位置创建的 Python 模型对象。您可以在注册时添加注释,如此处所示。名称和版本的组合在架构中必须唯一。您可以指定 ``conda_dependencies` 列表;指定的包将随模型一起部署。

from snowflake.ml.model import type_hints
mv = reg.log_model(clf,
                   model_name="my_model",
                   version_name="v1",
                   conda_dependencies=["scikit-learn"],
                   comment="My awesome ML model",
                   metrics={"score": 96},
                   sample_input_data=train_features,
                   task=type_hints.Task.TABULAR_BINARY_CLASSIFICATION)
Copy

log_model 的实参说明如下。

必填实参

实参

描述

model

受支持模型类型的 Python 模型对象。必须可序列化(“可执行 pickle 操作”)。

model_name

模型的名称,与 version_name 一同使用,以在注册表中标识模型。在登记模型之后,不能再更改名称。必须是 有效的 Snowflake 标识符

备注

模型名称和版本的组合在架构中必须唯一。

可选实参

实参

描述

version_name

指定模型版本的字符串,与 model_name 配合使用,以在注册表中标识模型。必须是 有效的 Snowflake 标识符。如果缺失,则自动生成人类可读的版本名称。

code_paths

加载或部署模型时要导入的代码目录的路径列表。

comment

注释,例如对于模型的描述。

conda_dependencies

您的模型所需的 Conda 包列表。此参数以 ` Conda 格式 <https://docs.conda.io/projects/conda/en/latest/user-guide/concepts/pkg-search.html (https://docs.conda.io/projects/conda/en/latest/user-guide/concepts/pkg-search.html)>`__(即 "[channel::]package [operator version]")指定包名称和可选的版本。如果您不指定通道,当模型在仓库上运行时,将假定使用 Snowflake 通道。对于在 Snowpark Container Services (SPCS) 上运行的模型,将假定使用 conda-forge。

ext_modules

要与模型一起执行 pickle 操作的外部模块列表。支持 scikit-learn、Snowpark ML、PyTorch、TorchScript 和自定义模型。

metrics

包含已链接到模型版本的指标的字典。

options

包含用于创建模型的选项的字典。以下选项适用于所有模型类型:

  • embed_local_ml_library:是否将本地 Snowpark ML 库的副本嵌入到模型中。默认:False

  • relax_version:是否放宽依赖项的版本约束。这将用 <=x.y, <(x+1) 等说明符替换版本说明符(如 ==x.y.z)。默认:True

  • method_options:包含各方法选项的字典,其中键是方法的名称,值是包含此处描述的一个或多个选项的字典。可用选项包括:

    • case_sensitive:指示方法及其签名是否区分大小写。在 SQL 中使用时,区分大小写的方法必须放在双引号里。此选项还允许在方法名称中使用非字母字符。默认:False

    • max_batch_size:在仓库中调用时,该方法将接受的最大批次大小。默认::code:`None`(自动确定批次大小)

个别模型类型可能支持其他选项。请参阅 使用内置模型类型

pip_requirements

模型所需 PyPI 包的包规格列表。仅支持在 Snowpark Container Services 中运行的模型。

python_version

运行模型的 Python 版本。默认为 None,指定仓库中可用的最新版本。

sample_input_data

一个 DataFrame,其中包含示例输入数据。模型所需的特征名称及其类型均提取自 DataFrame。必须为除 Snowpark ML 和 MLFlow 模型以及 Hugging Face pipeline 之外的所有模型提供此实参或 signatures

signatures

将方法签名建模为从目标方法名称到输入和输出签名的映射。必须为除 Snowpark sample_input_data 和 ML 模型以及 Hugging Face pipeline 之外的所有模型提供此实参或 MLFlow。

task

定义模型要解决的问题的任务。如果未指定,则尽最大努力从模型类推断模型任务,或者将其设置为 type_hints.Task.UNKNOWN。针对所有任务选项检查 snowflake.ml.model.type_hints

log_model 会返回一个 snowflake.ml.model.ModelVersion 对象,该对象表示已添加到注册表的模型的版本。

在登记之后,模型本身无法修改(不过可以更改其元数据)。要删除模型及其所有版本,请使用注册表的 delete_model 方法。

使用模型工件

登记模型后,其工件(支持模型的文件,包括其序列化的 Python 对象和各种元数据文件,例如其清单)在内部暂存区上提供。工件无法修改,但您可以查看或下载您拥有的模型的工件。

备注

拥有对模型的 USAGE 权限不允许您访问其工件;需要所有权。

例如,您可以使用 :doc:`GET 命令 </sql-reference/sql/get>`或 Snowpark Python 中的等效命令 `FileOperation.get <https://docs.snowflake.com/en/developer-guide/snowpark/reference/python/latest/api/snowflake.snowpark.FileOperation.get>`_ 访问暂存区中的模型工件。

但是,您不能使用常用的暂存区路径语法处理模型工件。取而代之,应使用 snow:// URL,这是在 Snowflake 中指定对象位置的更通用方法。例如,模型内的版本可以通过 snow://model/<model_name>/versions/<version_name>/ 形式的 URL 指定。

知道模型的名称和所需的版本后,可以使用 LIST 命令 查看模型的工件,如下所示:

LIST 'snow://model/my_model/versions/V3/';
Copy

输出类似于:

name                                      size                  md5                      last_modified
versions/V3/MANIFEST.yml           30639    2f6186fb8f7d06e737a4dfcdab8b1350        Thu, 18 Jan 2024 09:24:37 GMT
versions/V3/functions/apply.py      2249    e9df6db11894026ee137589a9b92c95d        Thu, 18 Jan 2024 09:24:37 GMT
versions/V3/functions/predict.py    2251    132699b4be39cc0863c6575b18127f26        Thu, 18 Jan 2024 09:24:37 GMT
versions/V3/model.zip             721663    e92814d653cecf576f97befd6836a3c6        Thu, 18 Jan 2024 09:24:37 GMT
versions/V3/model/env/conda.yml          332        1574be90b7673a8439711471d58ec746        Thu, 18 Jan 2024 09:24:37 GMT
versions/V3/model/model.yaml       25718    33e3d9007f749bb2e98f19af2a57a80b        Thu, 18 Jan 2024 09:24:37 GMT

要检索这些工件之一,请使用 SQL GET 命令:

GET 'snow://model/model_my_model/versions/V3/MANIFEST.yml'
Copy

或者使用 Snowpark Python 的等效命令:

session.file.get('snow://model/my_model/versions/V3/MANIFEST.yml', 'model_artifacts')
Copy

备注

模型工件的名称和组织可能因模型类型而异,并且可能会发生变化。前面的示例工件列表仅供说明之用,不具有权威性。

删除模型

使用注册表的 delete_model 方法删除模型及其所有版本:

reg.delete_model("mymodel")
Copy

小技巧

您也可以在 SQL 中使用 DROP MODEL 来删除模型。

从注册表获取模型

要获取有关每个模型的信息,请使用 show_models 方法:

model_df = reg.show_models()
Copy

小技巧

在 SQL 中,使用 SHOW MODELS 来获取模型列表。

show_models 的结果是一个 pandas DataFrame。下面列出了可用的列:

描述

created_on

模型的创建日期和时间。

name

模型的名称。

database_name

存储模型的数据库。

schema_name

存储模型的架构。

owner

拥有模型的角色。

comment

为模型添加注释。

versions

JSON 数组列出模型的版本。

default_version_name

引用没有版本的模型时使用的模型的版本。

要改为获取注册表中的模型列表(每个模型都作为一个 Model 实例),请使用 models 方法:

model_list = reg.models()
Copy

要根据名称从注册表获取对特定模型的引用,请使用注册表的 get_model 方法:

m = reg.get_model("MyModel")
Copy

备注

Model 实例不是原始登记的 Python 模型对象的副本;它们是对注册表中基础模型对象的引用。

有了对模型的引用后,无论是来自 models 方法返回的列表,还是通过使用 get_model 检索到的列表,都可以使用 其元数据其版本

查看和更新模型的元数据

您可以在注册表中查看和更新模型的元数据属性,包括其名称、注释、标签和指标。

检索和更新注释

使用模型的 comment 属性来检索和更新模型的注释:

print(m.comment)
m.comment = "A better description than the one I provided originally"
Copy

备注

description 属性是 comment 的同义词。前面的代码也可以这样编写:

print(m.description)
m.description = "A better description than the one I provided originally"
Copy

小技巧

在 SQL 中,还可以通过使用 ALTER MODEL 来设置模型的注释。

检索和更新标签

标签是元数据,用于登记模型的目的、算法、训练数据集、生命周期阶段或您选择的其他信息。您可在注册模型之时或之后的任何时间设置标签。您还可以更新现有标签的值或完全移除标签。

备注

您必须先使用 CREATE TAG 定义所有标签的名称(及其可能值)。请参阅 Object Tagging

要将模型的所有标签作为 Python 字典获取,请使用 show_tags

print(m.show_tags())
Copy

要添加新标签或更改现有标签的值,请使用 set_tag

m.set_tag("live_version", "v1")
Copy

要检索标签的值,请使用 get_tag

m.get_tag("live_version")
Copy

要移除标签,请使用 unset_tag

m.unset_tag("live_version")
Copy

小技巧

在 SQL 中,还可以通过使用 ALTER MODEL 来设置模型的注释。

重命名模型

使用 rename 方法重命名或移动模型。指定完全限定名称作为新名称,以将模型移动到不同的数据库或架构。

m.rename("MY_MODEL_TOO")
Copy

小技巧

在 SQL 中,也可以使用 ALTER MODEL 来重命名模型。

使用模型版本

一个模型可以有无限多个的版本,每个版本都由一个字符串标识。您可以使用自己喜欢的任何版本命名约定。登记模型实际上登记的是模型的 特定版本。要登记模型的其他版本,请再次调用具有相同 model_name 但不同 version_namelog_model

小技巧

在 SQL 中,使用 SHOW VERSIONS IN MODEL 来查看模型的版本。

模型的一个版本由 snowflake.ml.model.ModelVersion 类的一个实例表示。

要获取模型的所有版本的列表,请调用模型对象的 versions 方法。结果是 ModelVersion 实例的列表:

version_list = m.versions()
Copy

要改为以 DataFrame 的形式获取有关每个模型的信息,请调用模型的 show_versions 方法:

version_df = m.show_versions()
Copy

所得的 DataFrame 包含以下列:

描述

created_on

模型版本的创建日期和时间。

name

版本的名称。

database_name

存储版本的数据库。

schema_name

存储版本的架构。

model_name

此版本所属的模型名称。

is_default_version

布尔值,指示此版本是否为模型的默认版本。

functions

此版本中可用的函数名称的 JSON 数组。

metadata

JSON 对象包含作为键值对的元数据(如果未指定元数据,则为 {})。

user_data

来自模型定义清单的 user_data 部分的 JSON 对象(如果未指定用户数据,则为 {}

删除模型版本

您可以使用模型的 delete_version 方法删除模型版本:

m.delete_version("rc1")
Copy

小技巧

在 SQL 中,还可以通过使用 ALTER MODEL ...DROP VERSION 来删除模型版本。

默认版本

模型的版本可指定为默认模型。设置模型的 default 属性,以获取当前默认版本(作为 ModelVersion 对象)或对其进行更改(使用字符串):

default_version = m.default
m.default = "v2"
Copy

小技巧

在 SQL 中,使用 ALTER MODEL 来设置默认版本。

模型版本别名

可以使用 SQL ALTER MODEL 命令来为模型分配别名。每当需要版本名称时,都可以使用别名,例如在 Python 或 SQL 中获取对模型版本的引用时。给定别名一次只能分配给一个模型版本。

除了您创建的别名之外,以下系统别名在所有模型中都可用:

  • DEFAULT 指的是模型的默认版本。

  • FIRST 指的是按创建时间划分的模型的最旧版本。

  • LAST 指的是按创建时间划分的模型的最新版本。

您创建的别名不得与模型中的任何现有版本名称或别名(包括系统别名)相同。

获取对模型版本的引用

要以 ModelVersion 实例的形式获得对模型特定版本的引用,请使用模型的 version 方法。使用模型的 default 属性获取模型的默认版本:

m = reg.get_model("MyModel")

mv = m.version("v1")
mv = m.default
Copy

您引用模型的特定版本(例如本例中的 mv 变量)后,您就可以检索或更新其注释或指标,并调用模型的方法(或函数),如以下部分所示。

检索和更新注释

与模型一样,模型版本可以有注释,而注释可以通过模型版本的 commentdescription 属性访问和设置:

print(mv.comment)
print(mv.description)

mv.comment = "A model version comment"
mv.description = "Same as setting the comment"
Copy

小技巧

在 SQL 中,还可以通过使用 ALTER MODEL ...MODIFY VERSION 来更改模型的版本。

检索和更新指标

指标是用于跟踪预测准确度和其他模型版本特征的键值对。您可以在创建模型版本时设置指标,也可以使用 set_metric 方法设置指标。指标值可以是任何可序列化为 JSON 的 Python 对象,包括数字、字符串、列表和字典。与标签不同,指标名称和可能的值不需要预先定义。

可以使用 sklearn 的 accuracy_score 生成测试准确性指标:

from sklearn import metrics

test_accuracy = metrics.accuracy_score(test_labels, prediction)
Copy

类似地,可以使用 sklearn 生成混淆矩阵:

test_confusion_matrix = metrics.confusion_matrix(test_labels, prediction)
Copy

然后,可以将这些值设置为指标:

# scalar metric
mv.set_metric("test_accuracy", test_accuracy)

# hierarchical (dictionary) metric
mv.set_metric("evaluation_info", {"dataset_used": "my_dataset", "accuracy": test_accuracy, "f1_score": f1_score})

# multivalent (matrix) metric
mv.set_metric("confusion_matrix", test_confusion_matrix)
Copy

要以 Python 字典的形式检索模型版本的指标,请使用 show_metrics

metrics = mv.show_metrics()
Copy

要删除指标,请调用 delete_metric

mv.delete_metric("test_accuracy")
Copy

小技巧

在 SQL 中,还可以通过使用 ALTER MODEL ...MODIFY VERSION 来修改模型的指标(这些指标存储为元数据)。

检索模型说明

模型注册表可以解释模型的结果,通过计算 Shapley 值 (https://towardsdatascience.com/the-shapley-value-for-ml-models-f1100bff78d1) 告诉您哪些输入特征对预测贡献最大。默认情况下,此预览版功能在 Snowflake 8.31 及更高版本中通过底层模型的 explain 方法提供。在 SQL 中,可以调用 explain,或者在 Python 中,通过模型视图的 run 方法实现。

有关此功能的详细信息,请参阅 模型可解释性

导出模型版本

使用 mv.export 将模型的文件导出到本地目录;如果目录不存在,则创建该目录:

mv.export("~/mymodel/")
Copy

默认情况下,导出的文件包括代码、加载模型的环境和模型权重。要导出在仓库中运行模型所需的文件,请指定 export_mode = ExportMode.FULL

mv.export("~/mymodel/", export_mode=ExportMode.FULL)
Copy

加载模型版本

使用 mv.load 加载最初添加到注册表的原始 Python 模型对象。然后,您可以使用模型进行推理,就像在 Python 代码中定义的模型一样:

clf = mv.load()
Copy

为了确保从注册表加载的模型正常工作,目标 Python 环境(即 Python 解析器和所有库的版本)应该与登记模型所在的环境相同。在 load 调用中指定 force=True 以强制加载模型,即使环境有所不同。

小技巧

为了确保您的环境与托管模型的环境相同,请从模型注册表下载 conda 环境的副本:

conda_env = session.file.get("snow://model/<modelName>/versions/<versionName>/runtimes/python_runtime/env/conda.yml", ".")
open("~/conda.yml", "w").write(conda_env)
Copy

然后从该文件创建新的 conda 环境:

conda env create --name newenv --file=~/conda.yml
conda activate newenv
Copy

可选的 options 实参是用于加载模型的选项字典。目前,该实参仅支持 use_gpu 选项。

选项

类型

描述

默认值

use_gpu

bool

启用特定 GPU 的加载逻辑。

False

下面的示例说明了 options 实参的用法:

clf = mv.load(options={"use_gpu": True})
Copy

调用模型方法

模型版本可以具有 方法,这些方法是附加的函数,可执行这些函数来执行推理或其他模型操作。模型的版本可以具有不同的方法,这些方法的签名也可以有所不同。

要调用模型版本的方法,请使用 mv.run,其中 mvModelVersion 对象。指定要调用的函数的名称,并传递包含推理数据的 Snowpark 或 Pandas DataFrame,以及任何所需的参数。该方法在 Snowflake 仓库中执行。

该方法的返回值是 Snowpark 或 pandas DataFrame,匹配传入的 DataFrame 的类型。Snowpark DataFrames 采用延迟计算的方式,因此只有在调用 DataFrame 的 collectshowto_pandas 方法时才会运行此类方法。

备注

调用方法时,该方法会在连接注册表时所用会话内指定的仓库中运行。请参阅 指定仓库

下面的示例阐释了模型的 predict 方法的运行。除了推理数据(此处的 test_features)之外,此模型的 predict 方法不需要任何参数。如果确实需要,其他参数将作为附加参数在推理数据之后传递。

remote_prediction = mv.run(test_features, function_name="predict")
remote_prediction.show()   # assuming test_features is Snowpark DataFrame
Copy

要查看在给定模型上可以调用哪些方法,请调用 mv.show_functions。此方法的返回值是一个 ModelFunctionInfo 对象列表。这些对象中的每一个都包括以下属性:

  • name:可从 Python 或 SQL 调用的函数的名称。

  • target_method:原始登记的模型中 Python 方法的名称。

小技巧

您还可以在 SQL 中调用模型方法。请参阅 模型命令

共享模型

模型注册表可以存储两种类型的模型。可以使用 SHOW MODELS 输出中的 MODEL_TYPE 列区分它们。

  • CORTEX_FINETUNED:使用 Cortex Fine-tuning 生成的模型,这些模型不包含用户代码。要共享此类型的模型,请使用 数据共享

  • USER_MODEL:包含用户代码的模型,例如使用 Snowpark ML 建模类 开发的模型。这些模型目前无法共享。共享包含用户代码的模型的功能将在将来的版本中提供。

成本注意事项

使用 Snowflake Model Registry 会产生标准的基于 Snowflake 用量的成本。这些对象包括:

  • 存储模型工件、元数据和函数的成本。有关存储成本的一般信息,请参阅 探索存储成本

  • 在暂存区之间将文件复制到 Snowflake 的成本。请参阅 COPY FILES

  • 通过 Snowsight UI 或者 SQL 接口或 Python 接口进行无服务器模型对象操作的成本,例如显示模型和模型版本,以及更改模型注释、标签和指标。

  • 仓库计算成本,具体取决于模型的类型和用于推理的数据量。有关 Snowflake 计算成本的一般信息,请参阅 了解计算成本。以下操作会产生仓库计算成本:

    • 模型和版本创建操作

    • 调用一个模型的方法

语言: 中文