AI 中台建设中的模型管理:从单模型到模型市场的演进

AI 中台建设中的模型管理:从单模型到模型市场的演进

一、当模型数量突破两位数:手工管理体系的崩塌

AI 中台在起步阶段,团队往往只维护两三个模型——一个通用对话、一个代码生成、或许再加一个文生图。这个时期用 Git 仓库管理模型配置、手动部署、靠 Wiki 记录版本号,似乎都能运转。但当一个平台需要支撑业务方接入 30 个以上的模型时,这套管理体系会以肉眼可见的速度崩盘。

核心痛点集中在三个问题上。首先是配置碎片化。每个模型的推理参数、资源配额、加速引擎版本散落在不同的 YAML 文件和运维文档里,一个参数的变更可能被漏同步到 5 个环境。其次是版本一致性。A 团队升级了 vLLM 版本,B 团队还在用旧版,同一个模型在测试环境和生产环境表现不一致,排查半天发现是底层推理引擎版本差异造成的。第三是所有权混乱。模型镜像从谁那里继承的、安全补丁更新谁负责、SLA 由哪个团队兜底——这些问题在模型数量少的时候不算事,一旦规模化就变成定时炸弹。

基础设施不需要漂亮话,需要的是可复现、可审计、可追溯的管理体系。模型管理表面上看是 DevOps 问题,本质上是工程治理问题。

二、模型元数据中心化:从散落文档到单一事实来源

模型管理的核心命题是建立一个"单一事实来源"(Single Source of Truth)。我们把所有模型的元信息聚合到一个中心化注册表里,每个模型有一个唯一标识符,携带以下核心信息:模型名称与版本号、推理框架类型及版本(vLLM/TGI/TensorRT-LLM)、资源配置(GPU 类型/数量/显存/副本数)、推理参数(max_tokens/temperature/top_p 默认值)、模型权重的存储路径(对象存储 Bucket/Prefix)、安全合规标签(数据分级/是否涉及 PII)、负责人/所属团队/升级窗口。

这个注册表的实现没有追求花哨的框架。用 PostgreSQL 存结构化元数据,模型权重文件统一挂到对象存储上,前端搭一个轻量级的 Go + Gin 管理界面。关键不在技术栈,而在强制约束:所有模型的部署、扩缩容、版本升级,必须经过注册表的校验。注册表里没有记录的模型,不允许被调度器拉起。

这个架构的核心思想是:注册表即真相。调度器不信任任何外部输入,只信任注册表里的数据。任何没有通过注册表录入的模型,不会在任何集群上被调度运行。这个约束虽然粗暴,但在实践中最有效。

三、模型市场的产品化封装:让业务方自服务

注册表解决了运维层面的治理问题,但业务方仍然需要一个界面来发现和申请模型。这就引出了模型市场的设计。

模型市场的核心功能包括三个层次。第一层是模型目录,展示所有已上架的模型,带搜索、标签过滤和使用场景描述。第二层是接入流程,业务方选择模型后,系统自动生成 API Key 和调用文档,不需要人工审批,但在后台自动注入配额和限流策略。第三层是监控与计费,每次调用自动打点,Token 消耗、延迟分位数(P50/P99)、错误率都实时可见,成本按业务线拆分。

在实现上,模型市场本质上是一个 API 网关的扩展层。我们基于 Envoy 做了两层代理:外层根据 API Key 做认证和限流,内层根据请求中的model参数动态路由到对应的推理服务实例。这里有个值得注意的设计决策:我们不把路由逻辑放在模型市场里,而是通过配置下发到网关。模型市场只负责管理元数据和权限,网关独立负责流量转发——职责分离,故障域隔开。

Go 后端的关键代码结构大致如下:

// ModelRegistry 定义模型注册表的核心接口 type ModelRegistry interface { // Register 注册一个模型,校验必填字段 Register(ctx context.Context, model *ModelMeta) error // List 列出所有已上线的模型,支持标签过滤 List(ctx context.Context, filter ModelFilter) ([]*ModelMeta, error) // GetByID 根据模型 ID 获取元数据 GetByID(ctx context.Context, modelID string) (*ModelMeta, error) // UpdateStatus 更新模型状态(上线/下线/灰度) UpdateStatus(ctx context.Context, modelID string, status ModelStatus) error } // ModelMeta 模型元数据——注册表的单一事实来源 type ModelMeta struct { ID string `json:"id" validate:"required"` Name string `json:"name" validate:"required"` Version string `json:"version" validate:"required"` Framework string `json:"framework" validate:"required,oneof=vllm tgi tensorrt-llm triton"` GPU GPURequirement `json:"gpu"` Replicas int `json:"replicas" validate:"min=1,max=20"` InferenceParams InferenceConfig `json:"inference_params"` Owner string `json:"owner" validate:"required"` DataClass string `json:"data_class" validate:"required,oneof=public internal restricted"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` }

注册接口在执行写入前做三层校验:必填字段完整性、GPU 资源是否在当前集群可调度范围内、模型权重文件在对象存储中是否真实存在(HEAD 请求验证)。任何一层失败都直接拒绝注册,不让脏数据进入系统。

四、大规模管理的边界:这套方案解决不了什么

这套中心化注册 + 模型市场的方案并不是银弹。其适用边界和局限性需要清醒认知。

第一,多租户隔离是一个明显的短板。当前设计基于共享集群,通过 Namespace 和 ResourceQuota 做软隔离。如果业务方对数据安全有强隔离需求(如金融行业的私有化部署),这套方案无法替代独立的单租户集群。第二,模型权重的增量更新没有覆盖。当模型权重文件达到数百 GB 级别时,全量重新上传会显著拉长上线时间,但增量更新的实现复杂度远高于此处的投入产出比——我们在实践中选择了接受全量上传的代价。第三,模型市场的权限模型目前还比较简单(API Key 粒度的访问控制),如果需要更细粒度的"某个业务线只能使用某个模型的某个版本"这样的控制,需要引入 RBAC 层,这不在当前版本的设计范围内。

另外值得指出的是,这套方案为每个模型固定分配 GPU 副本,适合推理流量相对稳定的场景。如果流量波动剧烈、需要在多个模型之间弹性共享 GPU 池,那么模型市场的计费方式和调度策略需要重新设计。这个方向我们已经在下一阶段规划中,但当前版本不做。

五、总结

从单模型管理到模型市场,核心变化不是代码量的增长,而是治理范式的迁移——从依赖个人记忆和文档流转,过渡到依赖自动化约束和结构化元数据。

落地建议分三步走。第一步,先建立模型元数据的中心化注册表,强制所有新模型必须注册,这是代价最小、收益最大的动作。第二步,在注册表基础上构建 CI 流水线,实现镜像的自动构建和一致性升级,消除手工操作带来的版本漂移。第三步,在稳定性验证通过后,上线模型市场的前端界面,让业务方自助查找和接入模型,同时完善配额和限流策略。

关键判断标准:当一个模型从申请到上线的时间从"几天"缩短到"几十分钟",且全程不需要运维人员介入时,可以认为模型管理基础设施初步建成。