跨账户管好模型:MLflow 与 SageMaker Model Registry 的两种治理拓扑

2026-09-09 35 预计阅读时间: 1 分钟
来源: aws.amazon.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:11 分钟

自动把 MLflow 模型注册到 Amazon SageMaker AI Model Registry,只解决了“模型如何进入注册表”的问题。当开发、治理和生产环境分布在不同 AWS 账户后,真正棘手的是:谁拥有模型组、谁可以修改审批状态、推理制品放在哪里,以及账户被回收后模型是否仍可部署。

围绕跨账户治理,可以考虑两种拓扑:通过 AWS Resource Access Manager(AWS RAM)集中管理的中心辐射型,以及保留开发账户隔离边界的混合型。两者都可以沿用 MLflow 与 SageMaker Model Registry 的同步机制,但治理边界和发布路径明显不同。

中心辐射型:把治理入口收拢到一个账户

在中心辐射型架构中,治理账户充当 hub,开发、验证和生产账户作为 spoke。SageMaker Model Registry 中的模型包组由治理账户持有,再通过 AWS RAM 分享给指定账户或 AWS Organizations 组织单元。

一种典型职责划分是:

  • 开发账户运行训练任务和托管 MLflow,产生模型版本、指标及参数。
  • 治理账户持有模型包组,执行审批、审计和版本保留策略。
  • 生产账户只读取已批准版本,并创建模型或推理端点。
  • AWS RAM负责共享注册表资源,但不自动开放模型制品、KMS 密钥或容器镜像。

这种设计的优点是审批状态和发布记录集中,安全团队可以在一个账户内设置事件规则、审计查询和权限边界。代价则是 hub 容易成为共享依赖:配额、权限误配置或同步故障都可能影响多个团队。

还要明确一点:MLflow 到 Model Registry 的同步是传输机制,不应被当作完整的策略引擎。团队仍需决定哪个系统拥有最终审批权。例如,可以规定 MLflow 的标签描述实验状态,而 SageMaker 的 ModelApprovalStatus 才是生产发布依据,避免两个系统互相覆盖状态。

用 AWS RAM 分享模型包组

下面是一组可以改造的 AWS CLI 命令。假设模型包组位于治理账户,开发账户与治理账户处于同一个 AWS Organization,并且当前 CLI 身份有 SageMaker 和 RAM 管理权限。

先修改区域、账户 ID 和模型包组名称:

#!/usr/bin/env bash
set -euo pipefail

export AWS_REGION="us-east-1"
export GOVERNANCE_ACCOUNT_ID="111122223333"
export DEV_ACCOUNT_ID="444455556666"
export MODEL_PACKAGE_GROUP="fraud-detection"

GROUP_ARN="arn:aws:sagemaker:${AWS_REGION}:${GOVERNANCE_ACCOUNT_ID}:model-package-group/${MODEL_PACKAGE_GROUP}"

# 在治理账户创建模型包组;如果已经存在,可以跳过此命令。
aws sagemaker create-model-package-group \
  --region "${AWS_REGION}" \
  --model-package-group-name "${MODEL_PACKAGE_GROUP}" \
  --model-package-group-description "Governed fraud detection models"

# 将模型包组分享给开发账户。
aws ram create-resource-share \
  --region "${AWS_REGION}" \
  --name "share-${MODEL_PACKAGE_GROUP}" \
  --resource-arns "${GROUP_ARN}" \
  --principals "${DEV_ACCOUNT_ID}" \
  --no-allow-external-principals

如果使用 AWS Organizations,组织管理账户还需要预先执行一次:

aws ram enable-sharing-with-aws-organization

如果账户不在同一个组织,应根据安全策略改用 --allow-external-principals,并在接收账户接受 RAM 邀请:

aws ram get-resource-share-invitations --region us-east-1

aws ram accept-resource-share-invitation \
  --region us-east-1 \
  --resource-share-invitation-arn "替换为邀请 ARN"

以上命令是可改造的部署骨架。实际执行前,应确认目标区域支持相应资源共享方式,并检查 AWS RAM 为该资源类型提供的权限集合。RAM 共享也不能替代调用方自身的 IAM 权限;开发或生产角色仍需获得必要的 SageMaker API 权限。

更容易遗漏的是数据平面权限。一个模型包可能引用以下资源:

  • 开发账户 S3 存储桶中的模型制品;
  • 使用客户管理型 KMS 密钥加密的对象;
  • 私有 ECR 中的推理镜像;
  • 部署时由 SageMaker 使用的执行角色。

因此,“能看到模型版本”不等于“能部署模型版本”。稳定性要求较高时,可以在批准阶段把制品复制到治理账户或生产账户控制的 S3 存储桶,并使用目标账户可控的 KMS 密钥重新加密。这样即使开发账户被停用,已批准版本也不会失去依赖。

混合型:让开发账户保持隔离

混合型拓扑不要求所有开发账户直接写入中心注册表。每个开发账户可以保留自己的 MLflow 环境和本地模型包组;只有满足发布条件的版本,才通过受控流程进入治理账户。

这条边界适合以下情况:

  • 团队处理不同敏感级别的数据,不能共享训练环境或中间制品;
  • 开发账户生命周期较短,需要频繁创建和销毁;
  • 中央治理团队只希望接收候选版本,而不是所有实验版本;
  • 不同团队使用不同 MLflow 配置,但生产审批必须统一。

混合型通常需要显式的“晋级契约”。例如,开发流水线输出一个发布清单,治理流水线校验后再复制制品、登记版本并触发审批:

# release-manifest.yaml
schema_version: 1
model:
  name: fraud-detection
  mlflow_registered_model: fraud-detector
  mlflow_version: "42"
artifact:
  source_uri: s3://dev-ml-artifacts/models/fraud-detector/42/model.tar.gz
  sha256: "替换为真实的 SHA-256"
validation:
  dataset_id: fraud-holdout-2025-02
  metrics:
    auc: 0.941
    false_positive_rate: 0.018
  required_approvals:
    - model-owner
    - risk-reviewer
target:
  model_package_group: fraud-detection
  requested_status: PendingManualApproval

这个清单不是 SageMaker 的固定 API 格式,而是一种可以实践的流水线接口。治理任务应验证哈希值、允许的 S3 来源、指标阈值和审批人,然后再调用 SageMaker API。不要直接信任开发账户提交的 requested_status,更不要让晋级任务默认创建 Approved 版本。

混合型带来了更强的隔离,但也增加了复制成本和血缘映射工作。至少应永久记录以下对应关系:

  • MLflow registered model 名称与版本;
  • 源账户、训练作业和代码提交 ID;
  • SageMaker 模型包 ARN;
  • 制品原始哈希与复制后哈希;
  • 审批人、审批时间及策略版本。

用脚本审计中心注册表

无论采用哪种拓扑,都可以从治理账户定期读取模型包状态,并将结果送入日志或审计系统。下面的 Python 脚本可以直接运行;执行前配置有权读取目标模型包组的 AWS 凭证。

#!/usr/bin/env python3
import json
import os

import boto3

region = os.getenv("AWS_REGION", "us-east-1")
group = os.environ["MODEL_PACKAGE_GROUP"]

sagemaker = boto3.client("sagemaker", region_name=region)
paginator = sagemaker.get_paginator("list_model_packages")

records = []
for page in paginator.paginate(
    ModelPackageGroupName=group,
    SortBy="CreationTime",
    SortOrder="Descending",
):
    for item in page.get("ModelPackageSummaryList", []):
        detail = sagemaker.describe_model_package(
            ModelPackageName=item["ModelPackageArn"]
        )
        records.append(
            {
                "arn": item["ModelPackageArn"],
                "version": item.get("ModelPackageVersion"),
                "approval": detail.get("ModelApprovalStatus"),
                "creation_time": detail["CreationTime"].isoformat(),
                "metadata": detail.get("CustomerMetadataProperties", {}),
            }
        )

print(json.dumps(records, indent=2, ensure_ascii=False))

运行方式:

python3 -m pip install boto3
export AWS_REGION=us-east-1
export MODEL_PACKAGE_GROUP=fraud-detection
python3 audit_registry.py

可以进一步让脚本检查:已批准版本是否缺少 MLflow 版本号、制品哈希或代码提交 ID;是否存在长时间停留在 PendingManualApproval 的版本;生产环境引用的版本是否被意外改为 Rejected

选择拓扑时检查这些边界

如果组织希望统一发现、审批和审计模型,并且各账户处于一致的信任边界,中心辐射型通常更直接。若开发账户必须保持强隔离,或者中央平台只应接触经过筛选的候选版本,混合型更稳妥。

落地前可以逐项确认:

  • 是否已经指定 MLflow 与 SageMaker 之间唯一的审批事实来源;
  • RAM 分享的是哪些模型包组,主体是账户还是组织单元;
  • S3、KMS、ECR 与 SageMaker 执行角色是否具备完整的跨账户路径;
  • 同步和晋级操作是否幂等,重试会不会创建重复版本;
  • 开发账户关闭后,已批准模型是否仍可复现和部署;
  • 所有跨账户调用是否进入 CloudTrail,并能关联到模型版本;
  • 紧急撤销、回滚和权限收回是否经过演练。

真正可靠的模型治理,不只是把注册表放进中央账户,而是让模型元数据、制品、权限与审批记录拥有一致且可验证的生命周期。


相关推荐