跳到主要内容

Artifact Stores

工件存储(Artifact Store)是 MLflow Tracking 中的一个核心组件,MLflow 在此存储每次运行(Run)产生的(通常较大的)工件,例如模型权重(如 pickled 格式的 scikit-learn 模型)、图像(如 PNG 文件)、模型和数据文件(如 Parquet 文件)。请注意,参数、指标和标签等元数据存储在 后端存储(例如 PostGres、MySQL 或 MSSQL 数据库)中,这是 MLflow Tracking 的另一个组成部分。

配置工件存储

MLflow 默认将工件存储在本地(文件系统)的 ./mlruns 目录中,但也支持各种适合大数据存储的位置:Amazon S3、Azure Blob Storage、Google Cloud Storage、Backblaze B2、SFTP 服务器和 NFS。您可以通过 MLflow Tracking 服务器连接这些远程存储。有关如何连接所选远程存储的指导,请参阅 跟踪服务器设置 以及 支持的存储 中针对特定存储的章节。

管理工件存储访问权限

为了允许服务器和客户端访问工件位置,您应该像在任何其他场景中一样配置您的云服务提供商凭据。例如,对于 S3,您可以设置 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 环境变量,使用 IAM 角色,或者在 ~/.aws/credentials 中配置默认配置文件。

重要提示

工件存储位置的凭据和配置是在 跟踪服务器初始化期间配置一次的,而不是通过客户端 API 为每个基于工件的操作提供访问凭据。请注意,所有在此模式下有权访问跟踪服务器的用户,都将拥有通过此假定角色(assumed role)所服务的工件的访问权限

设置访问超时

您可以设置环境变量 MLFLOW_ARTIFACT_UPLOAD_DOWNLOAD_TIMEOUT(以秒为单位)来配置工件上传和下载的超时时间。如果未设置,MLflow 将使用底层存储客户端库的默认超时时间(例如 S3 使用 boto3 的默认值)。请注意,这是一个实验性功能,可能会根据需要进行修改。

设置用于记录的默认工件位置

MLflow 会自动将 artifact_uri 属性记录为 mlflow.entities.RunInfo 的一部分,以便您可以使用 mlflow.get_artifact_uri() API 检索历史运行的工件位置。此外,artifact_location 是记录在 mlflow.entities.Experiment 上的一个属性,用于设置给定实验中所有模型运行的默认工件存储位置。

重要提示

如果您在创建实验时没有指定 --default-artifact-root 或工件 URI(例如,mlflow experiments create --artifact-location s3://<my-bucket>),工件根目录将被设置为本地文件存储内的一个路径(执行您运行的计算机的硬盘驱动器)。通常这不是一个合适的选择,因为客户端和服务器可能指向不同的物理位置(也就是说,不同磁盘或计算机上的相同路径)。

工件存储支持的存储类型

Amazon S3 和 S3 兼容存储

要将工件存储在 S3 中(无论是 Amazon S3 还是 S3 兼容的替代品,如 MinIODigital Ocean Spaces),请指定 s3://<bucket>/<path> 格式的 URI。MLflow 会根据可用情况,从您机器的 IAM 角色、~/.aws/credentials 中的配置文件或环境变量 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 中获取访问 S3 的凭据。有关如何设置凭据的更多信息,请参阅 设置 AWS 开发凭据和区域

以下是配置 S3 存储访问常用的环境变量。S3 客户端的可配置参数完整列表可在 boto3 文档 中找到。

向 S3 上传传递额外参数

要添加 S3 文件上传的额外参数,请将 MLFLOW_S3_UPLOAD_EXTRA_ARGS 设置为一个键/值对的 JSON 对象。例如,如果您想使用 KMS 密钥 1234 上传到 KMS 加密的存储桶中:

bash
export MLFLOW_S3_UPLOAD_EXTRA_ARGS='{"ServerSideEncryption": "aws:kms", "SSEKMSKeyId": "1234"}'

有关可用额外参数的列表,请参阅 Boto3 ExtraArgs 文档

存储桶所有权验证

为了防止存储桶接管攻击(即删除的存储桶被另一个 AWS 账户重新创建),您可以将 MLFLOW_S3_EXPECTED_BUCKET_OWNER 设置为拥有您 S3 存储桶的预期 AWS 账户 ID。

bash
export MLFLOW_S3_EXPECTED_BUCKET_OWNER=123456789012

设置此项后,MLflow 将在所有 S3 API 调用中包含 ExpectedBucketOwner 参数。如果存储桶由其他账户拥有,S3 将拒绝该操作并返回拒绝访问错误,从而防止对工件的未经授权的访问。

这在以下情况下尤为重要:

  • S3 存储桶名称在所有 AWS 账户中是全局唯一的
  • 攻击者可能会删除并以相同名称重新创建存储桶
  • MLflow 可能会不知不觉地将工件发送到攻击者的存储桶

有关更多信息,请参阅 AWS S3 存储桶所有者条件文档

设置自定义 S3 端点

要将工件存储在自定义端点,请将 MLFLOW_S3_ENDPOINT_URL 设置为您的端点 URL。例如,如果您使用的是 Digital Ocean Spaces:

bash
export MLFLOW_S3_ENDPOINT_URL=https://<region>.digitaloceanspaces.com

如果您有一个位于 1.2.3.4 端口 9000 的 MinIO 服务器:

bash
export MLFLOW_S3_ENDPOINT_URL=http://1.2.3.4:9000

使用非 TLS 认证

如果 MinIO 服务器配置为使用 SSL 自签名证书或仅内部 CA 签名证书,您可以分别设置 MLFLOW_S3_IGNORE_TLSAWS_CA_BUNDLE 变量(不能同时设置!)来禁用证书签名检查,或者添加自定义 CA 捆绑包来执行此检查。

bash
export MLFLOW_S3_IGNORE_TLS=true
#or
export AWS_CA_BUNDLE=/some/ca/bundle.pem

设置存储桶区域

此外,如果 MinIO 服务器配置了非默认区域,您应该设置 AWS_DEFAULT_REGION 变量。

bash
export AWS_DEFAULT_REGION=my_region
警告

MLflow 跟踪服务器使用特定的保留关键字来生成限定路径。如果这些环境变量出现在客户端环境中,可能会导致路径解析问题。例如,在服务器端提供 --default-artifact-root $MLFLOW_S3_ENDPOINT_URL 在客户端设置 MLFLOW_S3_ENDPOINT_URL,将导致客户端对工件存储位置产生解析错误。在解析工件存储位置时,MLflow 客户端将使用 --default-artifact-root 提供的值,并将环境变量 MLFLOW_S3_ENDPOINT_URL 中提供的值作为后缀附加。根据 MLFLOW_S3_ENDPOINT_URL 的设置值,此场景下的工件存储路径将变成以下无效对象存储路径之一:https://<bucketname>.s3.<region>.amazonaws.com/<key>/<bucketname>/<key>s3://<bucketname>/<key>/<bucketname>/<key>。为防止路径解析问题,请确保从客户端环境中移除(unset)这些保留的环境变量

Azure Blob Storage

要将工件存储在 Azure Blob Storage 中,请指定 wasbs://<container>@<storage-account>.blob.core.windows.net/<path> 格式的 URI。MLflow 要求您的 Azure 存储访问凭据位于 AZURE_STORAGE_CONNECTION_STRINGAZURE_STORAGE_ACCESS_KEY 环境变量中,或者您的凭据配置方式能够被 DefaultAzureCredential() 类识别。优先级顺序如下:

  1. AZURE_STORAGE_CONNECTION_STRING
  2. AZURE_STORAGE_ACCESS_KEY
  3. DefaultAzureCredential()

您必须在 客户端应用程序和 MLflow 跟踪服务器上 同时设置这些选项之一。此外,您必须分别(在客户端和服务器上)运行 pip install azure-storage-blob 以访问 Azure Blob Storage。最后,如果您想使用 DefaultAzureCredential,则必须执行 pip install azure-identity;MLflow 默认不会声明对这些包的依赖。

您可以设置 MLflow 环境变量来配置工件上传和下载的超时时间:

  • MLFLOW_ARTIFACT_UPLOAD_DOWNLOAD_TIMEOUT - (实验性,可能会被更改或移除)设置工件上传/下载超时时间(秒)(默认:Azure blob 为 600)。

Google Cloud Storage

要将工件存储在 Google Cloud Storage 中,请指定 gs://<bucket>/<path> 格式的 URI。您应该按照 GCS 文档 中的说明,在客户端和服务器上配置访问 GCS 容器的凭据。最后,您必须运行 pip install google-cloud-storage(在客户端和服务器上)以访问 GCS;MLflow 默认不会声明对该包的依赖。

您可以使用以下环境变量来排查 GCS 读取超时问题(例如由于传输速度慢):

  • MLFLOW_ARTIFACT_UPLOAD_DOWNLOAD_TIMEOUT - (实验性,可能会被更改或移除)设置传输操作的标准超时时间(秒)(默认:GCS 为 60)。使用 -1 表示无限超时。
  • MLFLOW_GCS_UPLOAD_CHUNK_SIZE - 设置较大文件上传的标准分块大小(字节)(默认:104857600 即 100MiB),必须是 256 KB 的倍数。
  • MLFLOW_GCS_DOWNLOAD_CHUNK_SIZE - 设置较大文件下载的标准分块大小(字节)(默认:104857600 即 100MiB),必须是 256 KB 的倍数。

Backblaze B2

要将工件存储在 Backblaze B2 Cloud Storage 中,请指定 b2://<bucket>@<endpoint-host>/<path> 格式的 URI。端点主机通常是 s3.<region>.backblazeb2.com。您可以在 Backblaze 仪表板Buckets 页面上找到存储桶的端点。

MLflow 使用 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 环境变量进行身份验证。请从 Backblaze 仪表板的 App Keys 页面生成新的应用程序密钥(主应用程序密钥与 S3 兼容 API 不兼容)。

bash
export AWS_ACCESS_KEY_ID="your_b2_application_key_id"
export AWS_SECRET_ACCESS_KEY="your_b2_application_key"
export AWS_DEFAULT_REGION="us-east-005"

FTP 服务器

要将工件存储在 FTP 服务器中,请指定 ftp://user@host/path/to/directory 格式的 URI。URI 可以选择包含用于登录服务器的密码,例如 ftp://user:pass@host/path/to/directory

SFTP 服务器

要将工件存储在 SFTP 服务器中,请指定 sftp://user@host/path/to/directory 格式的 URI。您应该配置客户端,使其能够通过 SSH 在无需密码的情况下登录到 SFTP 服务器(例如公钥、ssh_config 中的身份文件等)。

支持使用 sftp://user:pass@host/ 格式进行登录。但出于安全考虑,不建议这样做。

使用此存储时,必须在服务器和客户端上安装 pysftp。运行 pip install pysftp 安装所需的包。

NFS

要将工件存储在 NFS 挂载中,请指定普通文件系统路径作为 URI,例如 /mnt/nfs。此路径必须在服务器和客户端上完全相同——您可能需要使用符号链接或重新挂载客户端以强制执行此属性。

HDFS

要将工件存储在 HDFS 中,请指定 hdfs: URI。它可以包含主机和端口:hdfs://<host>:<port>/<path>,或者仅包含路径:hdfs://<path>

对 HDFS 进行身份验证有两种方式:

  • 使用当前的 UNIX 账户授权
  • 使用以下环境变量的 Kerberos 凭据
bash
export MLFLOW_KERBEROS_TICKET_CACHE=/tmp/krb5cc_22222222
export MLFLOW_KERBEROS_USER=user_name_to_use

HDFS 工件存储通过 pyarrow.fs 模块进行访问,有关所需的配置和环境变量,请参阅 PyArrow 文档

删除行为

为了允许恢复 MLflow 运行,删除运行(Run)时,运行的元数据和工件不会自动从后端存储或工件存储中删除。MLflow 提供了 mlflow gc CLI,用于永久移除已删除运行的元数据和工件。

代理工件访问的分段上传(Multipart upload)

跟踪服务器支持在代理工件访问时使用分段上传来上传大型工件。要启用此功能,请将 MLFLOW_ENABLE_PROXY_MULTIPART_UPLOAD 设置为 true

bash
export MLFLOW_ENABLE_PROXY_MULTIPART_UPLOAD=true

在底层,跟踪服务器将向底层存储创建分段上传请求,为每个部分生成预签名 URL,并让客户端直接将部分上传到存储。一旦所有部分上传完毕,跟踪服务器将完成分段上传。数据不会全部通过跟踪服务器。

如果底层存储不支持分段上传,跟踪服务器将回退到单部分上传。如果支持分段上传但由于任何原因失败,将抛出异常。

MLflow 支持以下存储的代理工件访问分段上传:

  • Amazon S3
  • Google Cloud Storage

您可以配置以下环境变量:

  • MLFLOW_MULTIPART_UPLOAD_MINIMUM_FILE_SIZE - 指定记录工件时使用分段上传的最小文件大小(字节)(默认:500 MB)
  • MLFLOW_MULTIPART_UPLOAD_CHUNK_SIZE - 指定执行分段上传时使用的分块大小(字节)(默认:100 MB)