深色模式
模型注册中心 Model Registry
摘要:本文面向需要把"哪个模型版本在生产"变成可审计、可回滚、可自动化的平台工程师与 ML 负责人。讲解以 MLflow Model Registry 为代表的模型注册中心:版本管理、Stage(Staging/Production/Archived)、别名(alias)晋升、与 KServe 的集成,以及鉴权与隔离。适用版本:MLflow 2.x([版本相关:以官方 release 为准]),KServe v0.20([版本相关])。
适用版本与前提
- MLflow Tracking Server 已部署,后端数据库(PostgreSQL)与 artifact store(S3/MinIO)就绪
- KServe 已安装并支持
mlflow://存储 URI(或统一用对象存储 URI 桥接,见下文) - 已部署 Argo CD 等 GitOps 工具做声明式发布
核心概念:注册中心 ≠ 仓库
先区分两个常被混用的概念:
| 概念 | 存什么 | 例子 |
|---|---|---|
| 模型仓库 Model Repository | 权重文件本身 | 私有 HF Hub、MinIO 上的 s3://bucket/iris/v2/model |
| 模型注册中心 Model Registry | 版本、元数据、血缘、阶段 | MLflow Model Registry、KServe 引用的 storageUri |
注册中心的价值是把"生产用的是哪个版本"变成结构化、可查询、可审批的状态,而不是在 Slack 里说一句"上线新模型了"。
生产实践 1:注册模型并用别名晋升
MLflow 推荐用 alias(别名) 而非硬编码版本号做晋升,回滚只是移动指针:
python
# register_and_promote.py —— 示意,需在自有环境实测
from mlflow import MlflowClient
client = MlflowClient(tracking_uri="http://mlflow.yourdomain")
name = "demand-forecaster"
# 训练后注册一个新版本(run_id 来自训练作业)
registered = client.create_model_version(
name=name,
source="s3://mlflow-artifacts/0/abc123/artifacts/model",
run_id="abc123",
)
new_version = registered.version
# CI 通过后,把 candidate 指向新版本
client.set_registered_model_alias(name, "candidate", new_version)
# 人工/自动确认上线:把 champion 移到新版本,生产流量随之切换
client.set_registered_model_alias(name, "champion", new_version)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
用别名而非版本号
直接写 version=3 到生产配置会带来"改 YAML + 重发"的脆弱流程;用 champion/candidate 别名后,晋升变成一次 API 调用或一行 Git 改动,回滚也只是把 champion 指回旧版本。MLflow 还支持 staging/production 等 Stage,可与 alias 并用。
生产实践 2:KServe 直接引用 Registry 阶段
若集群的 KServe 启用了 MLflow storage initializer(见 kserve.md),可用 mlflow:// URI 直接指向阶段:
yaml
# kserve-from-registry.yaml
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
name: forecaster
namespace: models
spec:
predictor:
model:
modelFormat:
name: sklearn
storageUri: "mlflow://models/demand-forecaster/production"
# 也可用 /staging、/latest、/3 等1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
更稳妥的 GitOps 做法:CI 在模型晋升 champion 时,只更新 Git 里 InferenceService 的 storageUri,由 Argo CD 同步到集群,回滚即 git revert,全程可审计。
生产实践 3:CI 质量门禁(先测后晋)
yaml
# .github/workflows/promote.yml —— 示意
name: ai-quality
on: [pull_request]
jobs:
eval:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run quality checks # 用 Evidently / 自定义评估
run: python eval.py --ref data/reference.csv --cur data/current.csv
# 不达标则 CI 失败,alias 不移动,模型不进生产1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
把模型质量当代码质量
没有门禁的 Registry 只是个版本号列表。建议每个模型注册前跑固定数据集的回归/漂移/LLM-as-judge 检查,只有通过才允许 candidate -> champion。本文不给出具体阈值与 Benchmark(随业务不同),[未实测]。
验证
bash
# 查看已注册模型与版本
mlflow models list --name demand-forecaster # [版本相关: CLI 子命令随版本变化]
# 或用 REST/Python 客户端查询 alias
python - <<'PY'
from mlflow import MlflowClient
c = MlflowClient("http://mlflow.yourdomain")
print(c.get_model_version_by_alias("demand-forecaster", "champion").version)
PY
# 确认 KServe 拉到了对应产物
kubectl get inferenceservice forecaster -n models1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
回滚与清理
bash
# 回滚 = 把 champion 指回上一个稳定版本(无需重建镜像)
python - <<'PY'
from mlflow import MlflowClient
c = MlflowClient("http://mlflow.yourdomain")
c.set_registered_model_alias("demand-forecaster", "champion", <上一版本号>)
PY
# 若用 GitOps,则 git revert 并让 Argo CD 同步1
2
3
4
5
6
7
2
3
4
5
6
7
删除版本需谨慎
删除 ModelVersion 会移除其在 Registry 的元数据记录;若生产 storageUri 仍指向它(或对象存储被清理),推理服务将拉取失败。删除前先确认无 InferenceService 引用,并保留 artifact 一段时间。
故障排查
| 现象 | 原因 | 排查 |
|---|---|---|
| KServe 拉不到模型 | mlflow:// 未启用或凭证缺失 | 查 KServe storage initializer 是否支持 mlflow://;Secret 是否挂载 |
| 生产指向了错误版本 | 别名被误改 | 查 Registry 审计日志 / CI 流水线 |
| 多环境不一致 | staging 与 prod 用同一 Registry 未隔离 | 用 namespace 或独立 Registry 实例隔离环境 |
| 指标无法追溯 | 训练未 log_model 带环境 | 确保训练脚本记录 conda.yaml/requirements |
安全与合规
注册中心是越权与供应链风险点
- 默认无鉴权:开源 MLflow Server 默认不带认证,必须前置 oauth2-proxy 等对接企业 IdP(Okta/AD),否则任何人可读写模型版本与指标。
- 写权限收敛:仅 CI 服务账号与获批的 ML 负责人可
register/set_alias;普通数据科学家只读。用 RBAC + 独立 token 区分。 - artifact 隔离:推理命名空间不应直连 artifact store 长期凭证;用 KServe MLflow storage initializer 走 API + 临时凭证,保住 namespace 隔离。
- 防篡改:模型权重与元数据写入对象存储后建议启用版本化/不可变(object lock),防止被覆盖投毒。
成本与性能
- 存储成本:模型权重(尤其 LLM,单模型数十至数百 GB)是主要存储开销;对频繁训练的团队,用对象存储生命周期策略归档旧版本。
- 成本示例([价格随云厂商/时点变化,未实测]):100GB 模型权重存 S3 标准类约 0.02–0.023 USD/GB·月,单模型月存约 2–2.3 USD;成本主要来自 GPU 推理而非存储,详见 kserve.md 与 gpu-scheduling.md。
- 发布频率:Registry + 别名使"一天多次安全发布"可行,从而用小步快跑替代大版本豪赌,间接降低回滚成本。